summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--scripts/automation/trex_control_plane/client/trex_port.py10
-rwxr-xr-xscripts/automation/trex_control_plane/client/trex_stateless_client.py404
-rwxr-xr-xscripts/automation/trex_control_plane/client_utils/parsing_opts.py5
-rwxr-xr-xscripts/automation/trex_control_plane/common/trex_stats.py45
-rwxr-xr-xscripts/automation/trex_control_plane/console/trex_console.py76
-rw-r--r--scripts/automation/trex_control_plane/console/trex_tui.py127
6 files changed, 325 insertions, 342 deletions
diff --git a/scripts/automation/trex_control_plane/client/trex_port.py b/scripts/automation/trex_control_plane/client/trex_port.py
index 7e5942d4..94240f2a 100644
--- a/scripts/automation/trex_control_plane/client/trex_port.py
+++ b/scripts/automation/trex_control_plane/client/trex_port.py
@@ -56,7 +56,7 @@ class Port(object):
def err(self, msg):
return RC_ERR("port {0} : {1}".format(self.port_id, msg))
- def ok(self, data = "ACK"):
+ def ok(self, data = ""):
return RC_OK(data)
def get_speed_bps (self):
@@ -283,8 +283,12 @@ class Port(object):
if not self.is_acquired():
return self.err("port is not owned")
- if (not force) and (self.state != self.STATE_TX) and (self.state != self.STATE_PAUSE):
- return self.err("port is not transmitting")
+ # port is already stopped
+ if not force:
+ if (self.state == self.STATE_IDLE) or (self.state == self.state == self.STATE_STREAMS):
+ return self.ok()
+
+
params = {"handler": self.handler,
"port_id": self.port_id}
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 69cc9838..c5d7e053 100755
--- a/scripts/automation/trex_control_plane/client/trex_stateless_client.py
+++ b/scripts/automation/trex_control_plane/client/trex_stateless_client.py
@@ -67,7 +67,7 @@ class STLArgumentError(STLError):
if extended:
self.msg += "\n{0}".format(extended)
-
+# raised when timeout occurs
class STLTimeoutError(STLError):
def __init__ (self, timeout):
self.msg = "Timeout: operation took more than '{0}' seconds".format(timeout)
@@ -660,7 +660,7 @@ class CTRexStatelessClient(object):
return rc
- def __validate (self, port_id_list = None):
+ def __validate_traffic (self, port_id_list = None):
port_id_list = self.__ports(port_id_list)
rc = RC()
@@ -821,17 +821,8 @@ class CTRexStatelessClient(object):
# stop cmd
def __stop (self, port_id_list):
- # find the relveant ports
- active_ports = list(set(self.get_active_ports()).intersection(port_id_list))
-
- if not active_ports:
- msg = "No active traffic on provided ports"
- self.logger.log(format_text(msg, 'bold'))
- return RC_WARN(msg)
-
-
self.logger.pre_cmd("Stopping traffic on port(s) {0}:".format(port_id_list))
- rc = self.__stop_traffic(active_ports)
+ rc = self.__stop_traffic(port_id_list)
self.logger.post_cmd(rc)
if not rc:
@@ -842,16 +833,8 @@ class CTRexStatelessClient(object):
#update cmd
def __update (self, port_id_list, mult):
- # find the relevant ports
- active_ports = list(set(self.get_active_ports()).intersection(port_id_list))
-
- if not active_ports:
- msg = "No active traffic on provided ports"
- self.logger.log(format_text(msg, 'bold'))
- return RC_WARN(msg)
-
self.logger.pre_cmd("Updating traffic on port(s) {0}:".format(port_id_list))
- rc = self.__update_traffic(mult, active_ports)
+ rc = self.__update_traffic(mult, port_id_list)
self.logger.post_cmd(rc)
return rc
@@ -860,16 +843,8 @@ class CTRexStatelessClient(object):
# pause cmd
def __pause (self, port_id_list):
- # find the relevant ports
- active_ports = list(set(self.get_active_ports()).intersection(port_id_list))
-
- if not active_ports:
- msg = "No active traffic on provided ports"
- self.logger.log(format_text(msg, 'bold'))
- return RC_WARN(msg)
-
self.logger.pre_cmd("Pausing traffic on port(s) {0}:".format(port_id_list))
- rc = self.__pause_traffic(active_ports)
+ rc = self.__pause_traffic(port_id_list)
self.logger.post_cmd(rc)
return rc
@@ -878,16 +853,17 @@ class CTRexStatelessClient(object):
# resume cmd
def __resume (self, port_id_list):
- # find the relveant ports
- active_ports = list(set(self.get_active_ports()).intersection(port_id_list))
+ self.logger.pre_cmd("Resume traffic on port(s) {0}:".format(port_id_list))
+ rc = self.__resume_traffic(port_id_list)
+ self.logger.post_cmd(rc)
- if not active_ports:
- msg = "No active traffic on porvided ports"
- self.logger.log(format_text(msg, 'bold'))
- return RC_WARN(msg)
+ return rc
- self.logger.pre_cmd("Resume traffic on port(s) {0}:".format(port_id_list))
- rc = self.__resume_traffic(active_ports)
+
+ # validate port(s) profile
+ def __validate (self, port_id_list):
+ self.logger.pre_cmd("Validating streams on port(s) {0}:".format(port_id_list))
+ rc = self.__validate_traffic(port_id_list)
self.logger.post_cmd(rc)
return rc
@@ -985,52 +961,8 @@ class CTRexStatelessClient(object):
def _transmit_batch(self, batch_list):
return self.comm_link.transmit_batch(batch_list)
- ############# helper functions section ##############
-
-
- ########## port commands ##############
-
- ######################### Console (high level) API #########################
-
-
-
- # clear stats
- def cmd_clear(self, port_id_list):
-
- for port_id in port_id_list:
- self.ports[port_id].clear_stats()
-
- self.global_stats.clear_stats()
-
- return RC_OK()
-
-
- def cmd_invalidate (self, port_id_list):
- for port_id in port_id_list:
- self.ports[port_id].invalidate_stats()
-
- self.global_stats.invalidate()
-
- return RC_OK()
-
-
-
-
-
-
-
-
- # validate port(s) profile
- def cmd_validate (self, port_id_list):
- self.logger.pre_cmd("Validating streams on port(s) {0}:".format(port_id_list))
- rc = self.__validate(port_id_list)
- self.logger.post_cmd(rc)
-
- return rc
-
-
# stats
- def cmd_stats(self, port_id_list, stats_mask=set()):
+ def _get_formatted_stats(self, port_id_list, stats_mask=set()):
stats_opts = trex_stats.ALL_STATS_OPTS.intersection(stats_mask)
stats_obj = {}
@@ -1038,15 +970,24 @@ 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()):
+ def _get_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 ################
+ def _invalidate_stats (self, port_id_list):
+ for port_id in port_id_list:
+ self.ports[port_id].invalidate_stats()
+
+ self.global_stats.invalidate()
+
+ return RC_OK()
+
+
+
#################################
# ------ private methods ------ #
@@ -1089,6 +1030,7 @@ class CTRexStatelessClient(object):
############################ #############################
def __enter__ (self):
self.connect(mode = "RWF")
+ self.reset()
return self
def __exit__ (self, type, value, traceback):
@@ -1174,6 +1116,34 @@ class CTRexStatelessClient(object):
if port_obj.is_transmitting()]
+ # get stats
+ def get_stats (self, ports = None, async_barrier = True):
+ # by default use all ports
+ if ports == None:
+ ports = self.get_all_ports()
+
+ # verify valid port id list
+ rc = self._validate_port_list(ports)
+ if not rc:
+ raise STLArgumentError('ports', ports, valid_values = self.get_all_ports())
+
+ # check async barrier
+ if not type(async_barrier) is bool:
+ raise STLArgumentError('async_barrier', async_barrier)
+
+
+ # if the user requested a barrier - use it
+ if async_barrier:
+ rc = self.async_client.barrier()
+ if not rc:
+ raise STLError(rc)
+
+ return self.__get_stats(ports)
+
+ # return all async events
+ def get_events (self):
+ return self.event_handler.get_events()
+
############################ Commands #############################
############################ #############################
############################ #############################
@@ -1252,7 +1222,6 @@ class CTRexStatelessClient(object):
if not rc:
raise STLError(rc)
- return rc
# teardown - call after test is done
@@ -1282,7 +1251,6 @@ class CTRexStatelessClient(object):
if not rc:
raise STLError(rc)
- return rc
# reset the server by performing
@@ -1315,8 +1283,7 @@ class CTRexStatelessClient(object):
if not rc:
raise STLError(rc)
- # TODO: clear stats
- return RC_OK()
+ self.clear_stats()
# start cmd
@@ -1333,7 +1300,7 @@ class CTRexStatelessClient(object):
# by default use all ports
if ports == None:
- ports = self.get_all_ports()
+ ports = self.get_acquired_ports()
# verify valid port id list
rc = self._validate_port_list(ports)
@@ -1380,9 +1347,10 @@ class CTRexStatelessClient(object):
# stop traffic on ports
@__api_check(True)
def stop (self, ports = None):
- # by default use all ports
+
+ # by default the user means all the active ports
if ports == None:
- ports = self.get_all_ports()
+ ports = self.get_active_ports()
# verify valid port id list
rc = self._validate_port_list(ports)
@@ -1399,16 +1367,15 @@ class CTRexStatelessClient(object):
@__api_check(True)
def update (self, ports = None, mult = "1", total = False):
- # by default use all ports
+ # by default the user means all the active ports
if ports == None:
- ports = self.get_all_ports()
+ ports = self.get_active_ports()
# verify valid port id list
rc = self._validate_port_list(ports)
if not rc:
raise STLArgumentError('ports', ports, valid_values = self.get_all_ports())
-
# verify multiplier
mult_obj = parsing_opts.decode_multiplier(mult,
allow_update = True,
@@ -1426,15 +1393,15 @@ class CTRexStatelessClient(object):
if not rc:
raise STLError(rc)
- return rc
# pause traffic on ports
@__api_check(True)
def pause (self, ports = None):
- # by default use all ports
+
+ # by default the user means all the TX ports
if ports == None:
- ports = self.get_all_ports()
+ ports = self.get_transmitting_ports()
# verify valid port id list
rc = self._validate_port_list(ports)
@@ -1445,15 +1412,15 @@ class CTRexStatelessClient(object):
if not rc:
raise STLError(rc)
- return rc
# resume traffic on ports
@__api_check(True)
def resume (self, ports = None):
- # by default use all ports
+
+ # by default the user means all the paused ports
if ports == None:
- ports = self.get_all_ports()
+ ports = self.get_paused_ports()
# verify valid port id list
rc = self._validate_port_list(ports)
@@ -1464,63 +1431,55 @@ class CTRexStatelessClient(object):
if not rc:
raise STLError(rc)
- return rc
-
- # clear stats
- @__api_check(False)
- def clear_stats (self, ports = None, clear_global = True):
- # by default use all ports
+ @__api_check(True)
+ def validate (self, ports = None):
if ports == None:
- ports = self.get_all_ports()
+ ports = self.get_acquired_ports()
# verify valid port id list
rc = self._validate_port_list(ports)
if not rc:
raise STLArgumentError('ports', ports, valid_values = self.get_all_ports())
- # verify clear global
- if not type(clear_global) is bool:
- raise STLArgumentError('clear_global', clear_global)
-
-
- rc = self.__clear_stats(ports, clear_global)
+ rc = self.__validate(ports)
if not rc:
raise STLError(rc)
- # get stats
+ # clear stats
@__api_check(False)
- def get_stats (self, ports = None, async_barrier = True):
+ def clear_stats (self, ports = None, clear_global = True):
+
# by default use all ports
if ports == None:
- ports = self.get_all_ports()
+ ports = self.get_acquired_ports()
# verify valid port id list
rc = self._validate_port_list(ports)
if not rc:
raise STLArgumentError('ports', ports, valid_values = self.get_all_ports())
- # check async barrier
- if not type(async_barrier) is bool:
- raise STLArgumentError('async_barrier', async_barrier)
+ # verify clear global
+ if not type(clear_global) is bool:
+ raise STLArgumentError('clear_global', clear_global)
- # if the user requested a barrier - use it
- if async_barrier:
- rc = self.async_client.barrier()
- if not rc:
- raise STLError(rc)
+ rc = self.__clear_stats(ports, clear_global)
+ if not rc:
+ raise STLError(rc)
- return self.__get_stats(ports)
+
+
# wait while traffic is on, on timeout throw STLTimeoutError
@__api_check(True)
def wait_on_traffic (self, ports = None, timeout = 60):
- # by default use all ports
+
+ # by default use all acquired ports
if ports == None:
- ports = self.get_all_ports()
+ ports = self.get_acquired_ports()
# verify valid port id list
rc = self._validate_port_list(ports)
@@ -1536,7 +1495,9 @@ class CTRexStatelessClient(object):
raise STLTimeoutError(timeout)
-
+ # clear all async events
+ def clear_events (self):
+ self.event_handler.clear_events()
############################ Line #############################
############################ Commands #############################
@@ -1554,16 +1515,11 @@ class CTRexStatelessClient(object):
client.logger.log("Log:\n" + format_text(e.brief() + "\n", 'bold'))
return
- # don't want to print on error
- if not rc or rc.warn():
- return rc
+ # if got true - print time
+ if rc:
+ delta = time.time() - time1
+ client.logger.log(format_time(delta) + "\n")
- delta = time.time() - time1
-
-
- client.logger.log(format_time(delta) + "\n")
-
- return rc
return wrap
@@ -1583,19 +1539,24 @@ class CTRexStatelessClient(object):
return
# call the API
- mode = "RWF" if opts.force else "RW"
- self.connect(mode)
+ self.connect("RWF" if opts.force else "RW")
+ # true means print time
+ return True
@__console
def disconnect_line (self, line):
self.disconnect()
+
@__console
def reset_line (self, line):
self.reset()
+ # true means print time
+ return True
+
@__console
def start_line (self, line):
@@ -1629,6 +1590,9 @@ class CTRexStatelessClient(object):
opts.dry,
opts.total)
+ # true means print time
+ return True
+
@__console
@@ -1643,7 +1607,17 @@ class CTRexStatelessClient(object):
if opts is None:
return
- self.stop(opts.ports)
+ # find the relevant ports
+ ports = list(set(self.get_active_ports()).intersection(opts.ports))
+
+ if not ports:
+ self.logger.log(format_text("No active traffic on provided ports\n", 'bold'))
+ return
+
+ self.stop(ports)
+
+ # true means print time
+ return True
@__console
@@ -1660,7 +1634,17 @@ class CTRexStatelessClient(object):
if opts is None:
return
- self.update(opts.ports, opts.mult, opts.total)
+ # find the relevant ports
+ ports = list(set(self.get_active_ports()).intersection(opts.ports))
+
+ if not ports:
+ self.logger.log(format_text("No ports in valid state to update\n", 'bold'))
+ return
+
+ self.update(ports, opts.mult, opts.total)
+
+ # true means print time
+ return True
@__console
@@ -1675,7 +1659,17 @@ class CTRexStatelessClient(object):
if opts is None:
return
- self.pause(opts.ports)
+ # find the relevant ports
+ ports = list(set(self.get_transmitting_ports()).intersection(opts.ports))
+
+ if not ports:
+ self.logger.log(format_text("No ports in valid state to pause\n", 'bold'))
+ return
+
+ self.pause(ports)
+
+ # true means print time
+ return True
@__console
@@ -1690,7 +1684,17 @@ class CTRexStatelessClient(object):
if opts is None:
return
- return self.resume(opts.ports)
+ # find the relevant ports
+ ports = list(set(self.get_paused_ports()).intersection(opts.ports))
+
+ if not ports:
+ self.logger.log(format_text("No ports in valid state to resume\n", 'bold'))
+ return
+
+ return self.resume(ports)
+
+ # true means print time
+ return True
@__console
@@ -1711,8 +1715,9 @@ class CTRexStatelessClient(object):
+
@__console
- def print_formatted_stats_line (self, line):
+ def show_stats_line (self, line):
'''Fetch statistics from TRex server by port\n'''
# define a parser
parser = parsing_opts.gen_parser(self,
@@ -1724,7 +1729,7 @@ class CTRexStatelessClient(object):
opts = parser.parse_args(line.split())
if opts is None:
- return None
+ return
# determine stats mask
mask = self.__get_mask_keys(**self.__filter_namespace_args(opts, trex_stats.ALL_STATS_OPTS))
@@ -1732,137 +1737,60 @@ class CTRexStatelessClient(object):
# set to show all stats if no filter was given
mask = trex_stats.ALL_STATS_OPTS
-
- self.print_formatted_stats()
- stats = self.get_stats(opts.ports, mask)
+ stats_opts = trex_stats.ALL_STATS_OPTS.intersection(mask)
+
+ stats = self._get_formatted_stats(opts.ports, mask)
+
# print stats to screen
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):
+ @__console
+ def show_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__,
+ self.show_streams_line.__doc__,
parsing_opts.PORT_LIST_WITH_ALL,
- parsing_opts.STREAMS_MASK)#,
- #parsing_opts.FULL_OUTPUT)
+ parsing_opts.STREAMS_MASK)
opts = parser.parse_args(line.split())
if opts is None:
- return RC_ERR("bad command line parameters")
+ return
- streams = self.cmd_streams(opts.ports, set(opts.streams))
+ streams = self._get_streams(opts.ports, set(opts.streams))
if not streams:
- # we got no streams running
-
self.logger.log(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()
@__console
- def cmd_validate_line (self, line):
+ def validate_line (self, line):
'''validates port(s) stream configuration\n'''
parser = parsing_opts.gen_parser(self,
"validate",
- self.cmd_validate_line.__doc__,
+ self.validate_line.__doc__,
parsing_opts.PORT_LIST_WITH_ALL)
opts = parser.parse_args(line.split())
if opts is None:
- return RC_ERR("bad command line paramters")
-
- rc = self.cmd_validate(opts.ports)
- return rc
-
-
- def cmd_exit_line (self, line):
- self.logger.log(format_text("Exiting\n", 'bold'))
- # a way to exit
- return RC_ERR("exit")
-
-
- def cmd_wait_line (self, line):
- '''wait for a period of time\n'''
-
- parser = parsing_opts.gen_parser(self,
- "wait",
- self.cmd_wait_line.__doc__,
- parsing_opts.DURATION)
-
- opts = parser.parse_args(line.split())
- if opts is None:
- return RC_ERR("bad command line parameters")
-
- delay_sec = opts.duration if (opts.duration > 0) else 1
-
- self.logger.log(format_text("Waiting for {0} seconds...\n".format(delay_sec), 'bold'))
- time.sleep(delay_sec)
-
- return RC_OK()
-
- # run a script of commands
- def run_script_file (self, filename):
-
- self.logger.log(format_text("\nRunning script file '{0}'...".format(filename), 'bold'))
-
- rc = self.cmd_connect()
- if rc.bad():
return
- with open(filename) as f:
- script_lines = f.readlines()
-
- cmd_table = {}
-
- # register all the commands
- cmd_table['start'] = self.cmd_start_line
- cmd_table['stop'] = self.cmd_stop_line
- cmd_table['reset'] = self.cmd_reset_line
- cmd_table['wait'] = self.cmd_wait_line
- cmd_table['exit'] = self.cmd_exit_line
-
- for index, line in enumerate(script_lines, start = 1):
- line = line.strip()
- if line == "":
- continue
- if line.startswith("#"):
- continue
-
- sp = line.split(' ', 1)
- cmd = sp[0]
- if len(sp) == 2:
- args = sp[1]
- else:
- args = ""
-
- self.logger.log(format_text("Executing line {0} : '{1}'\n".format(index, line)))
-
- if not cmd in cmd_table:
- print "\n*** Error at line {0} : '{1}'\n".format(index, line)
- self.logger.log(format_text("unknown command '{0}'\n".format(cmd), 'bold'))
- return False
+ self.validate(opts.ports)
- rc = cmd_table[cmd](args)
- if rc.bad():
- return False
-
- self.logger.log(format_text("\n[Done]", 'bold'))
- return True
+ \ No newline at end of file
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 3cc32b1d..ba60c191 100755
--- a/scripts/automation/trex_control_plane/client_utils/parsing_opts.py
+++ b/scripts/automation/trex_control_plane/client_utils/parsing_opts.py
@@ -156,7 +156,7 @@ def decode_multiplier(val, allow_update = False, divide_count = 1):
def match_multiplier(val):
'''match some val against multiplier shortcut inputs '''
- result = decode_multiplier(val, allow_update = False)
+ result = decode_multiplier(val, allow_update = True)
if not result:
raise argparse.ArgumentTypeError(match_multiplier_help)
@@ -165,7 +165,7 @@ def match_multiplier(val):
def match_multiplier_strict(val):
'''match some val against multiplier shortcut inputs '''
- result = decode_multiplier(val, allow_update = True)
+ result = decode_multiplier(val, allow_update = False)
if not result:
raise argparse.ArgumentTypeError(match_multiplier_help)
@@ -252,6 +252,7 @@ OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'],
'default': False,
'help': "Starts TUI in xterm window"}),
+
FULL_OUTPUT: ArgumentPack(['--full'],
{'action': 'store_true',
'help': "Prompt full info in a JSON format"}),
diff --git a/scripts/automation/trex_control_plane/common/trex_stats.py b/scripts/automation/trex_control_plane/common/trex_stats.py
index 3d6ece7c..9c2cd7f1 100755
--- a/scripts/automation/trex_control_plane/common/trex_stats.py
+++ b/scripts/automation/trex_control_plane/common/trex_stats.py
@@ -260,7 +260,7 @@ class CTRexStats(object):
def __init__(self):
self.reference_stats = None
- self.latest_stats = {}
+ self.latest_stats = None
self.last_update_ts = time.time()
self.history = deque(maxlen = 10)
@@ -314,13 +314,11 @@ class CTRexStats(object):
self.last_update_ts = time.time()
- def get_stats (self):
- # copy and return
- return dict(self.latest_stats)
def clear_stats(self):
self.reference_stats = self.latest_stats
+
def invalidate (self):
self.latest_stats = {}
@@ -337,6 +335,10 @@ class CTRexStats(object):
return "N/A"
if not format:
+ if not field in self.reference_stats:
+ print "REF: " + str(self.reference_stats)
+ print "BASE: " + str(self.latest_stats)
+
return (self.latest_stats[field] - self.reference_stats[field])
else:
return format_num(self.latest_stats[field] - self.reference_stats[field], suffix)
@@ -403,6 +405,24 @@ class CGlobalStats(CTRexStats):
self.server_version = server_version
self._ports_dict = ports_dict_ref
+ def get_stats (self):
+ stats = {}
+
+ # absolute
+ stats['cpu_util'] = self.get("m_cpu_util")
+ stats['tx_bps'] = self.get("m_tx_bps")
+ stats['tx_pps'] = self.get("m_tx_pps")
+
+ stats['rx_bps'] = self.get("m_rx_bps")
+ stats['rx_pps'] = self.get("m_rx_pps")
+ stats['rx_drop_bps'] = self.get("m_rx_drop_bps")
+
+ # relatives
+ stats['queue_full'] = self.get_rel("m_total_queue_full")
+
+ return stats
+
+
def generate_stats(self):
return OrderedDict([("connection", "{host}, Port {port}".format(host=self.connection_info.get("server"),
port=self.connection_info.get("sync_port"))),
@@ -475,6 +495,23 @@ class CPortStats(CTRexStats):
return self
+ # for port we need to do something smarter
+ def get_stats (self):
+ stats = {}
+
+ stats['opackets'] = self.get_rel("opackets")
+ stats['ipackets'] = self.get_rel("ipackets")
+ stats['obytes'] = self.get_rel("obytes")
+ stats['ibytes'] = self.get_rel("ibytes")
+ stats['oerrors'] = self.get_rel("oerrors")
+ stats['ierrors'] = self.get_rel("ierrors")
+ stats['tx_bps'] = self.get("m_total_tx_bps")
+ stats['tx_pps'] = self.get("m_total_tx_pps")
+ stats['rx_bps'] = self.get("m_total_rx_bps")
+ stats['rx_pps'] = self.get("m_total_rx_pps")
+
+ return stats
+
def generate_stats(self):
diff --git a/scripts/automation/trex_control_plane/console/trex_console.py b/scripts/automation/trex_control_plane/console/trex_console.py
index 3ecbca06..34494561 100755
--- a/scripts/automation/trex_control_plane/console/trex_console.py
+++ b/scripts/automation/trex_control_plane/console/trex_console.py
@@ -438,13 +438,13 @@ class TRexConsole(TRexGeneralCmd):
def do_validate (self, line):
'''validates port(s) stream configuration\n'''
- self.stateless_client.cmd_validate_line(line)
+ self.stateless_client.validate_line(line)
@verify_connected
def do_stats(self, line):
'''Fetch statistics from TRex server by port\n'''
- self.stateless_client.stats_line(line)
+ self.stateless_client.show_stats_line(line)
def help_stats(self):
@@ -523,13 +523,8 @@ class TRexConsole(TRexGeneralCmd):
return
- set_window_always_on_top('trex_tui')
-
- save_verbose = self.stateless_client.get_verbose()
-
- self.stateless_client.set_verbose(self.stateless_client.logger.VERBOSE_QUIET)
- self.tui.show()
- self.stateless_client.set_verbose(save_verbose)
+ with self.stateless_client.logger.supress():
+ self.tui.show()
def help_tui (self):
@@ -601,6 +596,51 @@ class TRexConsole(TRexGeneralCmd):
do_h = do_history
+# run a script of commands
+def run_script_file (self, filename, stateless_client):
+
+ self.logger.log(format_text("\nRunning script file '{0}'...".format(filename), 'bold'))
+
+ with open(filename) as f:
+ script_lines = f.readlines()
+
+ cmd_table = {}
+
+ # register all the commands
+ cmd_table['start'] = stateless_client.start_line
+ cmd_table['stop'] = stateless_client.stop_line
+ cmd_table['reset'] = stateless_client.reset_line
+
+ for index, line in enumerate(script_lines, start = 1):
+ line = line.strip()
+ if line == "":
+ continue
+ if line.startswith("#"):
+ continue
+
+ sp = line.split(' ', 1)
+ cmd = sp[0]
+ if len(sp) == 2:
+ args = sp[1]
+ else:
+ args = ""
+
+ stateless_client.logger.log(format_text("Executing line {0} : '{1}'\n".format(index, line)))
+
+ if not cmd in cmd_table:
+ print "\n*** Error at line {0} : '{1}'\n".format(index, line)
+ stateless_client.logger.log(format_text("unknown command '{0}'\n".format(cmd), 'bold'))
+ return False
+
+ rc = cmd_table[cmd](args)
+ if rc.bad():
+ return False
+
+ stateless_client.logger.log(format_text("\n[Done]", 'bold'))
+
+ return True
+
+
#
def is_valid_file(filename):
if not os.path.isfile(filename):
@@ -609,6 +649,7 @@ def is_valid_file(filename):
return filename
+
def setParserOptions():
parser = argparse.ArgumentParser(prog="trex_console.py")
@@ -691,33 +732,20 @@ def main():
logger.log("Log:\n" + format_text(e.brief() + "\n", 'bold'))
logger.log(format_text("\nSwitching to read only mode - only few commands will be available", 'bold'))
-
- # if options.tui or not options.acquire:
- # rc = stateless_client.connect("RO")
- # else:
- # try:
- # rc = stateless_client.connect("RW")
- # except STLError as e:
- # logger.log(format_text("Switching to read only mode - only few commands will be available", 'bold'))
- #
- # with logger.supress():
- # rc = stateless_client.connect("RO")
-
-
# a script mode
if options.batch:
- cont = stateless_client.run_script_file(options.batch[0])
+ cont = run_script_file(options.batch[0], stateless_client)
if not cont:
return
# console
-
try:
console = TRexConsole(stateless_client, options.verbose)
logger.prompt_redraw = console.prompt_redraw
if options.tui:
+ set_window_always_on_top('trex_tui')
console.do_tui("")
else:
console.start()
diff --git a/scripts/automation/trex_control_plane/console/trex_tui.py b/scripts/automation/trex_control_plane/console/trex_tui.py
index 9e66a984..1e22b005 100644
--- a/scripts/automation/trex_control_plane/console/trex_tui.py
+++ b/scripts/automation/trex_control_plane/console/trex_tui.py
@@ -8,6 +8,7 @@ from client_utils import text_tables
from collections import OrderedDict
import datetime
from cStringIO import StringIO
+from client.trex_stateless_client import STLError
class SimpleBar(object):
def __init__ (self, desc, pattern):
@@ -60,7 +61,7 @@ class TrexTUIDashBoard(TrexTUIPanel):
def show (self):
- stats = self.stateless_client.cmd_stats(self.ports, trex_stats.COMPACT)
+ stats = self.stateless_client._get_formatted_stats(self.ports, trex_stats.COMPACT)
# print stats to screen
for stat_type, stat_data in stats.iteritems():
text_tables.print_table_with_header(stat_data.text_table, stat_type)
@@ -88,64 +89,44 @@ class TrexTUIDashBoard(TrexTUIPanel):
######### actions
def action_pause (self):
- rc = self.stateless_client.pause_traffic(self.mng.ports)
+ try:
+ rc = self.stateless_client.pause(ports = self.mng.ports)
+ except STLError:
+ pass
- ports_succeeded = []
- for rc_single, port_id in zip(rc.rc_list, self.mng.ports):
- if rc_single.rc:
- ports_succeeded.append(port_id)
+ return ""
- if len(ports_succeeded) > 0:
- return "paused traffic on port(s): {0}".format(ports_succeeded)
- else:
- return ""
def action_resume (self):
- rc = self.stateless_client.resume_traffic(self.mng.ports)
-
- ports_succeeded = []
- for rc_single, port_id in zip(rc.rc_list, self.mng.ports):
- if rc_single.rc:
- ports_succeeded.append(port_id)
+ try:
+ self.stateless_client.resume(ports = self.mng.ports)
+ except STLError:
+ pass
- if len(ports_succeeded) > 0:
- return "resumed traffic on port(s): {0}".format(ports_succeeded)
- else:
- return ""
+ return ""
def action_raise (self):
- mul = {'type': 'percentage', 'value': 5, 'op': 'add'}
- rc = self.stateless_client.update_traffic(mul, self.mng.ports)
+ try:
+ self.stateless_client.update(mult = "5%+", ports = self.mng.ports)
+ except STLError:
+ pass
- ports_succeeded = []
- for rc_single, port_id in zip(rc.rc_list, self.mng.ports):
- if rc_single.rc:
- ports_succeeded.append(port_id)
+ return ""
- if len(ports_succeeded) > 0:
- return "raised B/W by %5 on port(s): {0}".format(ports_succeeded)
- else:
- return ""
def action_lower (self):
- mul = {'type': 'percentage', 'value': 5, 'op': 'sub'}
- rc = self.stateless_client.update_traffic(mul, self.mng.ports)
-
- ports_succeeded = []
- for rc_single, port_id in zip(rc.rc_list, self.mng.ports):
- if rc_single.rc:
- ports_succeeded.append(port_id)
+ try:
+ self.stateless_client.update(mult = "5%-", ports = self.mng.ports)
+ except STLError:
+ pass
- if len(ports_succeeded) > 0:
- return "lowered B/W by %5 on port(s): {0}".format(ports_succeeded)
- else:
- return ""
+ return ""
def action_clear (self):
- self.stateless_client.cmd_clear(self.mng.ports)
+ self.stateless_client.clear_stats(self.mng.ports)
return "cleared all stats"
@@ -167,7 +148,7 @@ class TrexTUIPort(TrexTUIPanel):
def show (self):
- stats = self.stateless_client.cmd_stats([self.port_id], trex_stats.COMPACT)
+ stats = self.stateless_client._get_formatted_stats([self.port_id], trex_stats.COMPACT)
# print stats to screen
for stat_type, stat_data in stats.iteritems():
text_tables.print_table_with_header(stat_data.text_table, stat_type)
@@ -194,39 +175,44 @@ class TrexTUIPort(TrexTUIPanel):
# actions
def action_pause (self):
- rc = self.stateless_client.pause_traffic([self.port_id])
- if rc.good():
- return "port {0}: paused traffic".format(self.port_id)
- else:
- return ""
+ try:
+ self.stateless_client.pause(ports = [self.port_id])
+ except STLError:
+ pass
+
+ return ""
def action_resume (self):
- rc = self.stateless_client.resume_traffic([self.port_id])
- if rc.good():
- return "port {0}: resumed traffic".format(self.port_id)
- else:
- return ""
+ try:
+ self.stateless_client.resume(ports = [self.port_id])
+ except STLError:
+ pass
+
+ return ""
+
def action_raise (self):
- mul = {'type': 'percentage', 'value': 5, 'op': 'add'}
- rc = self.stateless_client.update_traffic(mul, [self.port_id])
+ mult = {'type': 'percentage', 'value': 5, 'op': 'add'}
- if rc.good():
- return "port {0}: raised B/W by 5%".format(self.port_id)
- else:
- return ""
+ try:
+ self.stateless_client.update(mult = mult, ports = [self.port_id])
+ except STLError:
+ pass
+
+ return ""
def action_lower (self):
- mul = {'type': 'percentage', 'value': 5, 'op': 'sub'}
- rc = self.stateless_client.update_traffic(mul, [self.port_id])
+ mult = {'type': 'percentage', 'value': 5, 'op': 'sub'}
- if rc.good():
- return "port {0}: lowered B/W by 5%".format(self.port_id)
- else:
- return ""
+ try:
+ self.stateless_client.update(mult = mult, ports = [self.port_id])
+ except STLError:
+ pass
+
+ return ""
def action_clear (self):
- self.stateless_client.cmd_clear([self.port_id])
+ self.stateless_client.clear_stats([self.port_id])
return "port {0}: cleared stats".format(self.port_id)
# log
@@ -423,7 +409,7 @@ class TrexTUI():
if self.state == self.STATE_ACTIVE:
# if no connectivity - move to lost connecitivty
if not self.stateless_client.async_client.is_alive():
- self.stateless_client.cmd_invalidate(self.pm.ports)
+ self.stateless_client._invalidate_stats(self.pm.ports)
self.state = self.STATE_LOST_CONT
@@ -438,11 +424,10 @@ class TrexTUI():
# restored connectivity - try to reconnect
elif self.state == self.STATE_RECONNECT:
- rc = self.stateless_client.connect("RO")
- if rc.good():
+ try:
+ self.stateless_client.connect("RO")
self.state = self.STATE_ACTIVE
- else:
- # maybe we lost it again
+ except STLError:
self.state = self.STATE_LOST_CONT