diff options
Diffstat (limited to 'scripts/automation')
17 files changed, 907 insertions, 501 deletions
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 b7580531..b25d5cd5 100644..100755 --- a/scripts/automation/trex_control_plane/client/trex_stateless_client.py +++ b/scripts/automation/trex_control_plane/client/trex_stateless_client.py @@ -19,7 +19,7 @@ class CTRexStatelessClient(object): self._conn_handler = {} def owned(func): - def wrapper(self, *args, **kwargs ) : + def wrapper(self, *args, **kwargs): if self._conn_handler.get(kwargs.get("port_id")): return func(self, *args, **kwargs) else: @@ -37,38 +37,66 @@ class CTRexStatelessClient(object): @owned def release(self, port_id=None): self._conn_handler.pop(port_id) - params = {"handler":self._conn_handler.get(port_id), + params = {"handler": self._conn_handler.get(port_id), "port_id": port_id} return self.transmit("release", params) @owned def add_stream(self, stream_id, stream_obj, port_id=None): assert isinstance(stream_obj, CStream) - params = {"handler":self._conn_handler.get(port_id), - "port_id":port_id, - "stream_id":stream_id, - "stream":stream_obj.dump()} + params = {"handler": self._conn_handler.get(port_id), + "port_id": port_id, + "stream_id": stream_id, + "stream": stream_obj.dump()} return self.transmit("add_stream", params) @owned def remove_stream(self, stream_id, port_id=None): - params = {"handler":self._conn_handler.get(port_id), - "port_id":port_id, - "stream_id":stream_id} + params = {"handler": self._conn_handler.get(port_id), + "port_id": port_id, + "stream_id": stream_id} return self.transmit("remove_stream", params) @owned def get_stream_list(self, port_id=None): - params = {"handler":self._conn_handler.get(port_id), - "port_id":port_id} + params = {"handler": self._conn_handler.get(port_id), + "port_id": port_id} return self.transmit("get_stream_list", params) @owned def get_stream(self, stream_id, port_id=None): - params = {"handler":self._conn_handler.get(port_id), - "port_id":port_id} + params = {"handler": self._conn_handler.get(port_id), + "port_id": port_id, + "stream_id": stream_id} return self.transmit("get_stream_list", params) + @owned + def start_traffic(self, port_id=None): + params = {"handler": self._conn_handler.get(port_id), + "port_id": port_id} + return self.transmit("start_traffic", params) + + @owned + def stop_traffic(self, port_id=None): + params = {"handler": self._conn_handler.get(port_id), + "port_id": port_id} + return self.transmit("stop_traffic", params) + + def get_global_stats(self): + return self.transmit("get_global_stats") + + @owned + def stop_traffic(self, port_id=None): + params = {"handler": self._conn_handler.get(port_id), + "port_id": port_id} + return self.transmit("stop_traffic", params) + + + + + + + def transmit(self, method_name, params={}): diff --git a/scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py b/scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py index ebeec77e..51bb3a14 100755 --- a/scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py +++ b/scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py @@ -17,13 +17,37 @@ class bcolors: BOLD = '\033[1m' UNDERLINE = '\033[4m' +# sub class to describe a batch +class BatchMessage(object): + def __init__ (self, rpc_client): + self.rpc_client = rpc_client + self.batch_list = [] + def add (self, method_name, params = {}): + + id, msg = self.rpc_client.create_jsonrpc_v2(method_name, params, encode = False) + self.batch_list.append(msg) + + def invoke (self, block = False): + if not self.rpc_client.connected: + return False, "Not connected to server" + + msg = json.dumps(self.batch_list) + + rc, resp_list = self.rpc_client.send_raw_msg(msg, block = False) + if len(self.batch_list) == 1: + return True, [(rc, resp_list)] + else: + return rc, resp_list + + +# JSON RPC v2.0 client class JsonRpcClient(object): def __init__ (self, default_server, default_port): self.verbose = False self.connected = False - + # default values self.port = default_port self.server = default_server @@ -63,7 +87,10 @@ class JsonRpcClient(object): print "[verbose] " + msg - def create_jsonrpc_v2 (self, method_name, params = {}): + def create_batch (self): + return BatchMessage(self) + + def create_jsonrpc_v2 (self, method_name, params = {}, encode = True): msg = {} msg["jsonrpc"] = "2.0" msg["method"] = method_name @@ -72,21 +99,22 @@ class JsonRpcClient(object): msg["id"] = self.id_gen.next() - return id, json.dumps(msg) - - def invoke_rpc_method (self, method_name, params = {}, block = False): - rc, msg = self._invoke_rpc_method(method_name, params, block) - if not rc: - self.disconnect() + if encode: + return id, json.dumps(msg) + else: + return id, msg - return rc, msg - def _invoke_rpc_method (self, method_name, params = {}, block = False): + def invoke_rpc_method (self, method_name, params = {}, block = False): if not self.connected: return False, "Not connected to server" id, msg = self.create_jsonrpc_v2(method_name, params) + return self.send_raw_msg(msg, block) + + + def send_raw_msg (self, msg, block = False): self.verbose_msg("Sending Request To Server:\n\n" + self.pretty_json(msg) + "\n") if block: @@ -95,6 +123,7 @@ class JsonRpcClient(object): try: self.socket.send(msg, flags = zmq.NOBLOCK) except zmq.error.ZMQError as e: + self.disconnect() return False, "Failed To Get Send Message" got_response = False @@ -112,22 +141,41 @@ class JsonRpcClient(object): sleep(0.2) if not got_response: + self.disconnect() return False, "Failed To Get Server Response" self.verbose_msg("Server Response:\n\n" + self.pretty_json(response) + "\n") # decode + + # batch ? response_json = json.loads(response) + if isinstance(response_json, list): + rc_list = [] + + for single_response in response_json: + rc, msg = self.process_single_response(single_response) + rc_list.append( (rc, msg) ) + + return True, rc_list + + else: + rc, msg = self.process_single_response(response_json) + return rc, msg + + + def process_single_response (self, response_json): + if (response_json.get("jsonrpc") != "2.0"): return False, "Malfromed Response ({0})".format(str(response)) - if (response_json.get("id") != id): - return False, "Server Replied With Bad ID ({0})".format(str(response)) - # error reported by server if ("error" in response_json): - return True, response_json["error"]["message"] + if "specific_err" in response_json["error"]: + return False, response_json["error"]["specific_err"] + else: + return False, response_json["error"]["message"] # if no error there should be a result if ("result" not in response_json): @@ -136,17 +184,7 @@ class JsonRpcClient(object): return True, response_json["result"] - def ping_rpc_server(self): - - return self.invoke_rpc_method("ping", block = False) - - def get_rpc_server_status (self): - return self.invoke_rpc_method("get_status") - - def query_rpc_server(self): - return self.invoke_rpc_method("get_supported_cmds") - - + def set_verbose(self, mode): self.verbose = mode @@ -182,12 +220,6 @@ class JsonRpcClient(object): self.connected = True - # ping the server - rc, err = self.ping_rpc_server() - if not rc: - self.disconnect() - return rc, err - return True, "" @@ -205,11 +237,213 @@ class JsonRpcClient(object): def is_connected(self): return self.connected - def __del__(self): print "Shutting down RPC client\n" if hasattr(self, "context"): self.context.destroy(linger=0) -if __name__ == "__main__": - pass +# MOVE THIS TO DAN'S FILE +class TrexStatelessClient(JsonRpcClient): + + def __init__ (self, server, port, user): + + super(TrexStatelessClient, self).__init__(server, port) + + self.user = user + self.port_handlers = {} + + self.supported_cmds = [] + self.system_info = None + self.server_version = None + + + def whoami (self): + return self.user + + def ping_rpc_server(self): + + return self.invoke_rpc_method("ping", block = False) + + def get_rpc_server_version (self): + return self.server_version + + def get_system_info (self): + return self.system_info + + def get_supported_cmds(self): + return self.supported_cmds + + def get_port_count (self): + if not self.system_info: + return 0 + + return self.system_info["port_count"] + + # refresh the client for transient data + def refresh (self): + + # get server versionrc, msg = self.get_supported_cmds() + rc, msg = self.invoke_rpc_method("get_version") + if not rc: + self.disconnect() + return rc, msg + + self.server_version = msg + + # get supported commands + rc, msg = self.invoke_rpc_method("get_supported_cmds") + if not rc: + self.disconnect() + return rc, msg + + self.supported_cmds = [str(x) for x in msg if x] + + # get system info + rc, msg = self.invoke_rpc_method("get_system_info") + if not rc: + self.disconnect() + return rc, msg + + self.system_info = msg + + return True, "" + + def connect (self): + rc, err = super(TrexStatelessClient, self).connect() + if not rc: + return rc, err + + return self.refresh() + + + # take ownership over ports + def take_ownership (self, port_id_array, force = False): + if not self.connected: + return False, "Not connected to server" + + batch = self.create_batch() + + for port_id in port_id_array: + batch.add("acquire", params = {"port_id":port_id, "user":self.user, "force":force}) + + rc, resp_list = batch.invoke() + if not rc: + return rc, resp_list + + for i, rc in enumerate(resp_list): + if rc[0]: + self.port_handlers[port_id_array[i]] = rc[1] + + return True, resp_list + + + def release_ports (self, port_id_array): + batch = self.create_batch() + + for port_id in port_id_array: + + # let the server handle un-acquired errors + if self.port_handlers.get(port_id): + handler = self.port_handlers[port_id] + else: + handler = "" + + batch.add("release", params = {"port_id":port_id, "handler":handler}) + + + rc, resp_list = batch.invoke() + if not rc: + return rc, resp_list + + for i, rc in enumerate(resp_list): + if rc[0]: + self.port_handlers.pop(port_id_array[i]) + + return True, resp_list + + def get_owned_ports (self): + return self.port_handlers.keys() + + # fetch port stats + def get_port_stats (self, port_id_array): + if not self.connected: + return False, "Not connected to server" + + batch = self.create_batch() + + # empty list means all + if port_id_array == []: + port_id_array = list([x for x in xrange(0, self.system_info["port_count"])]) + + for port_id in port_id_array: + + # let the server handle un-acquired errors + if self.port_handlers.get(port_id): + handler = self.port_handlers[port_id] + else: + handler = "" + + batch.add("get_port_stats", params = {"port_id":port_id, "handler":handler}) + + + rc, resp_list = batch.invoke() + + return rc, resp_list + + # snapshot will take a snapshot of all your owned ports for streams and etc. + def snapshot(self): + + + if len(self.get_owned_ports()) == 0: + return {} + + snap = {} + + batch = self.create_batch() + + for port_id in self.get_owned_ports(): + + batch.add("get_port_stats", params = {"port_id": port_id, "handler": self.port_handlers[port_id]}) + batch.add("get_stream_list", params = {"port_id": port_id, "handler": self.port_handlers[port_id]}) + + rc, resp_list = batch.invoke() + if not rc: + return rc, resp_list + + # split the list to 2s + index = 0 + for port_id in self.get_owned_ports(): + if not resp_list[index] or not resp_list[index + 1]: + snap[port_id] = None + continue + + # fetch the first two + stats = resp_list[index][1] + stream_list = resp_list[index + 1][1] + + port = {} + port['status'] = stats['status'] + port['stream_list'] = [] + + # get all the streams + if len(stream_list) > 0: + batch = self.create_batch() + for stream_id in stream_list: + batch.add("get_stream", params = {"port_id": port_id, "stream_id": stream_id, "handler": self.port_handlers[port_id]}) + + rc, stream_resp_list = batch.invoke() + if not rc: + port = {} + + port['streams'] = {} + for i, resp in enumerate(stream_resp_list): + if resp[0]: + port['streams'][stream_list[i]] = resp[1] + + snap[port_id] = port + + # move to next one + index += 2 + + + return snap diff --git a/scripts/automation/trex_control_plane/client_utils/packet_builder.py b/scripts/automation/trex_control_plane/client_utils/packet_builder.py index 0505d7f1..1c643335 100755 --- a/scripts/automation/trex_control_plane/client_utils/packet_builder.py +++ b/scripts/automation/trex_control_plane/client_utils/packet_builder.py @@ -75,6 +75,7 @@ class CTRexPktBuilder(object): attr: str a string representation of the sub-field to be set: + + "src" for source + "dst" for destination @@ -84,6 +85,7 @@ class CTRexPktBuilder(object): ip_type : str a string representation of the IP version to be set: + + "ipv4" for IPv4 + "ipv6" for IPv6 @@ -115,6 +117,7 @@ class CTRexPktBuilder(object): attr: str a string representation of the sub-field to be set: + + "src" for source + "dst" for destination @@ -227,6 +230,7 @@ class CTRexPktBuilder(object): val : int value of attribute. This value will be set "ontop" of the existing value using bitwise "OR" operation. + .. tip:: It is very useful to use dpkt constants to define the values of these fields. :raises: @@ -408,9 +412,9 @@ class CTRexPktBuilder(object): trim_size = val_size*2 hdr_offset, field_abs_offset = self._calc_offset(layer_name, hdr_field, val_size) self.vm.add_flow_man_inst(range_name, size=val_size, operation=operation, - init_value=str(init_val), - min_value=str(start_val), - max_value=str(end_val)) + init_value=init_val, + min_value=start_val, + max_value=end_val) self.vm.add_write_flow_inst(range_name, field_abs_offset) self.vm.set_vm_off_inst_field(range_name, "add_value", add_val) self.vm.set_vm_off_inst_field(range_name, "is_big_endian", is_big_endian) diff --git a/scripts/automation/trex_control_plane/common/trex_status_e.py b/scripts/automation/trex_control_plane/common/trex_status_e.py index 3ad85014..fbfe92af 100755 --- a/scripts/automation/trex_control_plane/common/trex_status_e.py +++ b/scripts/automation/trex_control_plane/common/trex_status_e.py @@ -1,6 +1,6 @@ #!/router/bin/python
-# import outer_packages
+import outer_packages # import this to overcome doc building import error by sphinx
from enum import Enum
diff --git a/scripts/automation/trex_control_plane/console/trex_console.py b/scripts/automation/trex_control_plane/console/trex_console.py index 6514a51c..3aeab901 100644 --- a/scripts/automation/trex_control_plane/console/trex_console.py +++ b/scripts/automation/trex_control_plane/console/trex_console.py @@ -4,9 +4,13 @@ import cmd import json import ast import argparse +import random +import string + import sys import trex_root_path -from client_utils.jsonrpc_client import JsonRpcClient + +from client_utils.jsonrpc_client import TrexStatelessClient import trex_status class TrexConsole(cmd.Cmd): @@ -34,7 +38,7 @@ class TrexConsole(cmd.Cmd): # set verbose on / off def do_verbose (self, line): - '''shows or set verbose mode\n''' + '''Shows or set verbose mode\n''' if line == "": print "\nverbose is " + ("on\n" if self.verbose else "off\n") @@ -78,6 +82,98 @@ class TrexConsole(cmd.Cmd): print "\n*** " + msg + "\n" return + def do_force_acquire (self, line): + '''Acquires ports by force\n''' + + self.do_acquire(line, True) + + def parse_ports_from_line (self, line): + port_list = set() + + if line: + for port_id in line.split(' '): + if (not port_id.isdigit()) or (int(port_id) < 0) or (int(port_id) >= self.rpc_client.get_port_count()): + print "Please provide a list of ports seperated by spaces between 0 and {0}".format(self.rpc_client.get_port_count() - 1) + return None + + port_list.add(int(port_id)) + + port_list = list(port_list) + + else: + port_list = [i for i in xrange(0, self.rpc_client.get_port_count())] + + return port_list + + def do_acquire (self, line, force = False): + '''Acquire ports\n''' + + port_list = self.parse_ports_from_line(line) + if not port_list: + return + + print "\nTrying to acquire ports: " + (" ".join(str(x) for x in port_list)) + "\n" + + rc, resp_list = self.rpc_client.take_ownership(port_list, force) + + if not rc: + print "\n*** " + resp_list + "\n" + return + + for i, rc in enumerate(resp_list): + if rc[0]: + print "Port {0} - Acquired".format(port_list[i]) + else: + print "Port {0} - ".format(port_list[i]) + rc[1] + + print "\n" + + def do_release (self, line): + '''Release ports\n''' + + if line: + port_list = self.parse_ports_from_line(line) + else: + port_list = self.rpc_client.get_owned_ports() + + if not port_list: + return + + rc, resp_list = self.rpc_client.release_ports(port_list) + + + print "\n" + + for i, rc in enumerate(resp_list): + if rc[0]: + print "Port {0} - Released".format(port_list[i]) + else: + print "Port {0} - Failed to release port, probably not owned by you or port is under traffic" + + print "\n" + + def do_get_port_stats (self, line): + '''Get ports stats\n''' + + port_list = self.parse_ports_from_line(line) + if not port_list: + return + + rc, resp_list = self.rpc_client.get_port_stats(port_list) + + if not rc: + print "\n*** " + resp_list + "\n" + return + + for i, rc in enumerate(resp_list): + if rc[0]: + print "\nPort {0} stats:\n{1}\n".format(port_list[i], self.rpc_client.pretty_json(json.dumps(rc[1]))) + else: + print "\nPort {0} - ".format(i) + rc[1] + "\n" + + print "\n" + + def do_connect (self, line): '''Connects to the server\n''' @@ -97,10 +193,7 @@ class TrexConsole(cmd.Cmd): print "\n*** " + msg + "\n" return - rc, msg = self.rpc_client.query_rpc_server() - - if rc: - self.supported_rpc = [str(x) for x in msg if x] + self.supported_rpc = self.rpc_client.get_supported_cmds() def do_rpc (self, line): '''Launches a RPC on the server\n''' @@ -135,7 +228,7 @@ class TrexConsole(cmd.Cmd): rc, msg = self.rpc_client.invoke_rpc_method(method, params) if rc: - print "\nServer Response:\n\n" + json.dumps(msg) + "\n" + print "\nServer Response:\n\n" + self.rpc_client.pretty_json(json.dumps(msg)) + "\n" else: print "\n*** " + msg + "\n" #print "Please try 'reconnect' to reconnect to server" @@ -151,7 +244,7 @@ class TrexConsole(cmd.Cmd): trex_status.show_trex_status(self.rpc_client) def do_quit(self, line): - '''exit the client\n''' + '''Exit the client\n''' return True def do_disconnect (self, line): @@ -166,6 +259,10 @@ class TrexConsole(cmd.Cmd): else: print msg + "\n" + def do_whoami (self, line): + '''Prints console user name\n''' + print "\n" + self.rpc_client.whoami() + "\n" + def postcmd(self, stop, line): if self.rpc_client.is_connected(): self.prompt = "TRex > " @@ -216,6 +313,13 @@ class TrexConsole(cmd.Cmd): print "{:<30} {:<30}".format(cmd + " - ", help) + # do + #def do_snapshot (self, line): + + #for key, value in self.rpc_client.snapshot()[1]['streams'].iteritems(): + #print str(key) + " " + str(value) + + # aliasing do_exit = do_EOF = do_q = do_quit @@ -230,6 +334,10 @@ def setParserOptions (): default = 5050, type = int) + parser.add_argument("-u", "--user", help = "User Name [default is random generated]\n", + default = 'user_' + ''.join(random.choice(string.digits) for _ in range(5)), + type = str) + return parser def main (): @@ -237,7 +345,7 @@ def main (): options = parser.parse_args(sys.argv[1:]) # RPC client - rpc_client = JsonRpcClient(options.server, options.port) + rpc_client = TrexStatelessClient(options.server, options.port, options.user) # console try: diff --git a/scripts/automation/trex_control_plane/console/trex_status.py b/scripts/automation/trex_control_plane/console/trex_status.py index 54853ea3..b881f9f5 100644 --- a/scripts/automation/trex_control_plane/console/trex_status.py +++ b/scripts/automation/trex_control_plane/console/trex_status.py @@ -11,13 +11,21 @@ import datetime g_curses_active = False -# +# simple percetange show def percentage (a, total): x = int ((float(a) / total) * 100) return str(x) + "%" +# simple float to human readable +def float_to_human_readable (size, suffix = "bps"): + for unit in ['','K','M','G']: + if abs(size) < 1024.0: + return "%3.1f %s%s" % (size, unit, suffix) + size /= 1024.0 + return "NaN" + # panel object -class TrexStatusPanel(): +class TrexStatusPanel(object): def __init__ (self, h, l, y, x, headline): self.h = h self.l = l @@ -44,12 +52,245 @@ class TrexStatusPanel(): def getwin (self): return self.win -def float_to_human_readable (size, suffix = "bps"): - for unit in ['','K','M','G']: - if abs(size) < 1024.0: - return "%3.1f %s%s" % (size, unit, suffix) - size /= 1024.0 - return "NaN" + +# total stats (ports + global) +class Stats(): + def __init__ (self, rpc_client, port_list, interval = 100): + + self.rpc_client = rpc_client + + self.port_list = port_list + self.port_stats = {} + + self.interval = interval + self.delay_count = 0 + + def get_port_stats (self, port_id): + if self.port_stats.get(port_id): + return self.port_stats[port_id] + else: + return None + + def query_sync (self): + self.delay_count += 1 + if self.delay_count < self.interval: + return + + self.delay_count = 0 + + # query global stats + + # query port stats + + rc, resp_list = self.rpc_client.get_port_stats(self.port_list) + if not rc: + return + + for i, rc in enumerate(resp_list): + if rc[0]: + self.port_stats[self.port_list[i]] = rc[1] + + +# various kinds of panels + +# Server Info Panel +class ServerInfoPanel(TrexStatusPanel): + def __init__ (self, h, l, y, x, status_obj): + + super(ServerInfoPanel, self).__init__(h, l, y ,x ,"Server Info:") + + self.status_obj = status_obj + + def draw (self): + + if self.status_obj.server_version == None: + return + + self.clear() + + connection_details = self.status_obj.rpc_client.get_connection_details() + + self.getwin().addstr(3, 2, "{:<30} {:30}".format("Server:",self.status_obj.server_sys_info["hostname"] + ":" + str(connection_details['port']))) + self.getwin().addstr(4, 2, "{:<30} {:30}".format("Version:", self.status_obj.server_version["version"])) + self.getwin().addstr(5, 2, "{:<30} {:30}".format("Build:", + self.status_obj.server_version["build_date"] + " @ " + + self.status_obj.server_version["build_time"] + " by " + + self.status_obj.server_version["built_by"])) + + self.getwin().addstr(6, 2, "{:<30} {:30}".format("Server Uptime:", self.status_obj.server_sys_info["uptime"])) + self.getwin().addstr(7, 2, "{:<30} {:<3} / {:<30}".format("DP Cores:", str(self.status_obj.server_sys_info["dp_core_count"]) + + " cores", self.status_obj.server_sys_info["core_type"])) + + self.getwin().addstr(9, 2, "{:<30} {:<30}".format("Ports Count:", self.status_obj.server_sys_info["port_count"])) + + ports_owned = " ".join(str(x) for x in self.status_obj.rpc_client.get_owned_ports()) + + if not ports_owned: + ports_owned = "None" + + self.getwin().addstr(10, 2, "{:<30} {:<30}".format("Ports Owned:", ports_owned)) + +# general info panel +class GeneralInfoPanel(TrexStatusPanel): + def __init__ (self, h, l, y, x, status_obj): + + super(GeneralInfoPanel, self).__init__(h, l, y ,x ,"General Info:") + + self.status_obj = status_obj + + def draw (self): + pass + +# all ports stats +class PortsStatsPanel(TrexStatusPanel): + def __init__ (self, h, l, y, x, status_obj): + + super(PortsStatsPanel, self).__init__(h, l, y ,x ,"Trex Ports:") + + self.status_obj = status_obj + + def draw (self): + + self.clear() + + owned_ports = self.status_obj.rpc_client.get_owned_ports() + if not owned_ports: + self.getwin().addstr(3, 2, "No Owned Ports - Please Acquire One Or More Ports") + return + + # table header + self.getwin().addstr(3, 2, "{:^15} {:^15} {:^15} {:^15} {:^15} {:^15} {:^15}".format( + "Port ID", "Tx [pps]", "Tx [bps]", "Tx [bytes]", "Rx [pps]", "Rx [bps]", "Rx [bytes]")) + + # port loop + self.status_obj.stats.query_sync() + + for i, port_index in enumerate(owned_ports): + + port_stats = self.status_obj.stats.get_port_stats(port_index) + + if port_stats: + self.getwin().addstr(5 + (i * 4), 2, "{:^15} {:^15,} {:^15,} {:^15,} {:^15,} {:^15,} {:^15,}".format( + "{0} ({1})".format(str(port_index), self.status_obj.server_sys_info["ports"][port_index]["speed"]), + port_stats["tx_pps"], + port_stats["tx_bps"], + port_stats["total_tx_bytes"], + port_stats["rx_pps"], + port_stats["rx_bps"], + port_stats["total_rx_bytes"])) + + else: + self.getwin().addstr(5 + (i * 4), 2, "{:^15} {:^15} {:^15} {:^15} {:^15} {:^15} {:^15}".format( + "{0} ({1})".format(str(port_index), self.status_obj.server_sys_info["ports"][port_index]["speed"]), + "N/A", + "N/A", + "N/A", + "N/A", + "N/A", + "N/A")) + +# control panel +class ControlPanel(TrexStatusPanel): + def __init__ (self, h, l, y, x, status_obj): + + super(ControlPanel, self).__init__(h, l, y, x, "") + + self.status_obj = status_obj + + def draw (self): + self.clear() + + self.getwin().addstr(1, 2, "'g' - general, '0-{0}' - specific port, 'f' - freeze, 'c' - clear stats, 'p' - ping server, 'q' - quit" + .format(self.status_obj.rpc_client.get_port_count() - 1)) + + index = 3 + + cut = len(self.status_obj.log) - 4 + if cut < 0: + cut = 0 + + for l in self.status_obj.log[cut:]: + self.getwin().addstr(index, 2, l) + index += 1 + +# specific ports panels +class SinglePortPanel(TrexStatusPanel): + def __init__ (self, h, l, y, x, status_obj, port_id): + + super(SinglePortPanel, self).__init__(h, l, y, x, "Port {0}".format(port_id)) + + self.status_obj = status_obj + self.port_id = port_id + + def draw (self): + y = 3 + + self.clear() + + if not self.port_id in self.status_obj.rpc_client.get_owned_ports(): + self.getwin().addstr(y, 2, "Port {0} is not owned by you, please acquire the port for more info".format(self.port_id)) + return + + # streams + self.getwin().addstr(y, 2, "Streams:", curses.A_UNDERLINE) + y += 2 + + # stream table header + self.getwin().addstr(y, 2, "{:^15} {:^15} {:^15} {:^15} {:^15} {:^15} {:^15}".format( + "Stream ID", "Enabled", "Type", "Self Start", "ISG", "Next Stream", "VM")) + y += 2 + + # streams + if 'streams' in self.status_obj.snapshot[self.port_id]: + for stream_id, stream in self.status_obj.snapshot[self.port_id]['streams'].iteritems(): + self.getwin().addstr(y, 2, "{:^15} {:^15} {:^15} {:^15} {:^15} {:^15} {:^15}".format( + stream_id, + ("True" if stream['stream']['enabled'] else "False"), + stream['stream']['mode']['type'], + ("True" if stream['stream']['self_start'] else "False"), + stream['stream']['isg'], + (stream['stream']['next_stream_id'] if stream['stream']['next_stream_id'] != -1 else "None"), + ("{0} instr.".format(len(stream['stream']['vm'])) if stream['stream']['vm'] else "None"))) + + y += 1 + + # new section - traffic + y += 2 + + self.getwin().addstr(y, 2, "Traffic:", curses.A_UNDERLINE) + y += 2 + + self.status_obj.stats.query_sync() + port_stats = self.status_obj.stats.get_port_stats(self.port_id) + + + # table header + self.getwin().addstr(y, 2, "{:^15} {:^15} {:^15} {:^15} {:^15} {:^15} {:^15}".format( + "Port ID", "Tx [pps]", "Tx [bps]", "Tx [bytes]", "Rx [pps]", "Rx [bps]", "Rx [bytes]")) + + y += 2 + + if port_stats: + self.getwin().addstr(y, 2, "{:^15} {:^15,} {:^15,} {:^15,} {:^15,} {:^15,} {:^15,}".format( + "{0} ({1})".format(str(self.port_id), self.status_obj.server_sys_info["ports"][self.port_id]["speed"]), + port_stats["tx_pps"], + port_stats["tx_bps"], + port_stats["total_tx_bytes"], + port_stats["rx_pps"], + port_stats["rx_bps"], + port_stats["total_rx_bytes"])) + + else: + self.getwin().addstr(y, 2, "{:^15} {:^15} {:^15} {:^15} {:^15} {:^15} {:^15}".format( + "{0} ({1})".format(str(self.port_id), self.status_obj.server_sys_info["ports"][self.port_id]["speed"]), + "N/A", + "N/A", + "N/A", + "N/A", + "N/A", + "N/A")) + + y += 2 # status object class TrexStatus(): @@ -58,58 +299,78 @@ class TrexStatus(): self.log = [] self.rpc_client = rpc_client + self.snapshot = self.rpc_client.snapshot() + + # fetch server info self.get_server_info() - def get_server_info (self): - rc, msg = self.rpc_client.get_rpc_server_status() + # create stats objects + self.stats = Stats(rpc_client, self.rpc_client.get_owned_ports()) - if rc: - self.server_status = msg - else: - self.server_status = None + # register actions + self.actions = {} + self.actions[ord('q')] = self.action_quit + self.actions[ord('p')] = self.action_ping + self.actions[ord('f')] = self.action_freeze - def add_log_event (self, msg): - self.log.append("[{0}] {1}".format(str(datetime.datetime.now().time()), msg)) + self.actions[ord('g')] = self.action_show_ports_stats - def add_panel (self, h, l, y, x, headline): - win = curses.newwin(h, l, y, x) - win.erase() - win.box() + for port_id in xrange(0, self.rpc_client.get_port_count()): + self.actions[ord('0') + port_id] = self.action_show_port_generator(port_id) - win.addstr(1, 2, headline) - win.refresh() + + # all ports stats + def action_show_ports_stats (self): + self.add_log_event("Switching to all ports view") + self.stats_panel = self.ports_stats_panel + + return True - panel.new_panel(win) - panel1 = panel.new_panel(win) - panel1.top() + # function generator for different ports requests + def action_show_port_generator (self, port_id): + def action_show_port(): + self.add_log_event("Switching panel to port {0}".format(port_id)) + self.stats_panel = self.ports_panels[port_id] - return win, panel1 + return True - # static info panel - def update_info (self): - if self.server_status == None: - return + return action_show_port - self.info_panel.clear() + def action_freeze (self): + self.update_active = not self.update_active + self.add_log_event("Update continued" if self.update_active else "Update stopped") - connection_details = self.rpc_client.get_connection_details() + return True - self.info_panel.getwin().addstr(3, 2, "{:<30} {:30}".format("Server:", connection_details['server'] + ":" + str(connection_details['port']))) - self.info_panel.getwin().addstr(4, 2, "{:<30} {:30}".format("Version:", self.server_status["general"]["version"])) - self.info_panel.getwin().addstr(5, 2, "{:<30} {:30}".format("Build:", - self.server_status["general"]["build_date"] + " @ " + self.server_status["general"]["build_time"] + " by " + self.server_status["general"]["version_user"])) + def action_quit(self): + return False - self.info_panel.getwin().addstr(6, 2, "{:<30} {:30}".format("Server Uptime:", self.server_status["general"]["uptime"])) + def action_ping (self): + self.add_log_event("Pinging RPC server") + + rc, msg = self.rpc_client.ping_rpc_server() + if rc: + self.add_log_event("Server replied: '{0}'".format(msg)) + else: + self.add_log_event("Failed to get reply") + + return True + + def get_server_info (self): + + self.server_version = self.rpc_client.get_rpc_server_version() + self.server_sys_info = self.rpc_client.get_system_info() - # general stats - def update_general (self, gen_stats): - pass + + def add_log_event (self, msg): + self.log.append("[{0}] {1}".format(str(datetime.datetime.now().time()), msg)) # control panel def update_control (self): self.control_panel.clear() - self.control_panel.getwin().addstr(1, 2, "'f' - freeze, 'c' - clear stats, 'p' - ping server, 'q' - quit") + self.control_panel.getwin().addstr(1, 2, "'g' - general, '0-{0}' - specific port, 'f' - freeze, 'c' - clear stats, 'p' - ping server, 'q' - quit" + .format(self.rpc_client.get_port_count() - 1)) index = 3 @@ -125,42 +386,37 @@ class TrexStatus(): self.max_y = self.stdscr.getmaxyx()[0] self.max_x = self.stdscr.getmaxyx()[1] - # create cls panel - self.main_panel = TrexStatusPanel(int(self.max_y * 0.8), self.max_x / 2, 0,0, "Trex Ports:") + self.server_info_panel = ServerInfoPanel(int(self.max_y * 0.3), self.max_x / 2, int(self.max_y * 0.5), self.max_x /2, self) + self.general_info_panel = GeneralInfoPanel(int(self.max_y * 0.5), self.max_x / 2, 0, self.max_x /2, self) + self.control_panel = ControlPanel(int(self.max_y * 0.2), self.max_x , int(self.max_y * 0.8), 0, self) - self.general_panel = TrexStatusPanel(int(self.max_y * 0.6), self.max_x / 2, 0, self.max_x /2, "General Statistics:") + # those can be switched on the same place + self.ports_stats_panel = PortsStatsPanel(int(self.max_y * 0.8), self.max_x / 2, 0, 0, self) - self.info_panel = TrexStatusPanel(int(self.max_y * 0.2), self.max_x / 2, int(self.max_y * 0.6), self.max_x /2, "Server Info:") + self.ports_panels = {} + for i in xrange(0, self.rpc_client.get_port_count()): + self.ports_panels[i] = SinglePortPanel(int(self.max_y * 0.8), self.max_x / 2, 0, 0, self, i) - self.control_panel = TrexStatusPanel(int(self.max_y * 0.2), self.max_x , int(self.max_y * 0.8), 0, "") + # at start time we point to the main one + self.stats_panel = self.ports_stats_panel + self.stats_panel.panel.top() panel.update_panels(); self.stdscr.refresh() + return + def wait_for_key_input (self): ch = self.stdscr.getch() - if (ch != curses.ERR): - # stop/start status - if (ch == ord('f')): - self.update_active = not self.update_active - self.add_log_event("Update continued" if self.update_active else "Update stopped") - - elif (ch == ord('p')): - self.add_log_event("Pinging RPC server") - rc, msg = self.rpc_client.ping_rpc_server() - if rc: - self.add_log_event("Server replied: '{0}'".format(msg)) - else: - self.add_log_event("Failed to get reply") - - # c - clear stats - elif (ch == ord('c')): - self.add_log_event("Statistics cleared") - - elif (ch == ord('q')): - return False - else: - self.add_log_event("Unknown key pressed {0}".format("'" + chr(ch) + "'" if chr(ch).isalpha() else "")) + # no key , continue + if ch == curses.ERR: + return True + + # check for registered function + if ch in self.actions: + return self.actions[ch]() + else: + self.add_log_event("Unknown key pressed, please see legend") return True @@ -185,12 +441,17 @@ class TrexStatus(): if not rc: break - self.update_control() - self.update_info() + self.server_info_panel.draw() + self.general_info_panel.draw() + self.control_panel.draw() + + # can be different kinds of panels + self.stats_panel.panel.top() + self.stats_panel.draw() panel.update_panels(); self.stdscr.refresh() - sleep(0.1) + sleep(0.01) def show_trex_status_internal (stdscr, rpc_client): diff --git a/scripts/automation/trex_control_plane/doc/api/index.rst b/scripts/automation/trex_control_plane/doc/api/index.rst index 8233a634..cfdc6917 100755 --- a/scripts/automation/trex_control_plane/doc/api/index.rst +++ b/scripts/automation/trex_control_plane/doc/api/index.rst @@ -1,9 +1,8 @@ API Reference ============= -The T-Rex API reference section is currently a work in progress. -**T-Rex Modules** +**TRex Modules** .. toctree:: :maxdepth: 4 @@ -11,7 +10,7 @@ The T-Rex API reference section is currently a work in progress. client_code exceptions -**T-Rex JSON Template** +**TRex JSON Template** .. toctree:: :maxdepth: 4 diff --git a/scripts/automation/trex_control_plane/doc/api/json_fields.rst b/scripts/automation/trex_control_plane/doc/api/json_fields.rst index b1a2af7c..9e32d23e 100755 --- a/scripts/automation/trex_control_plane/doc/api/json_fields.rst +++ b/scripts/automation/trex_control_plane/doc/api/json_fields.rst @@ -1,23 +1,23 @@ -T-Rex JSON Template
-===================
+TRex JSON Template
+==================
-Whenever T-Rex is publishing live data, it uses JSON notation to describe the data-object.
+Whenever TRex is publishing live data, it uses JSON notation to describe the data-object.
-Each client may parse it diffrently, however this page will describe the values meaning when published by T-Rex server.
+Each client may parse it differently, however this page will describe the values meaning when published by TRex server.
Main Fields
-----------
-Each T-Rex server-published JSON object contains data divided to main fields under which the actual data lays.
+Each TRex server-published JSON object contains data divided to main fields under which the actual data lays.
These main fields are:
+-----------------------------+----------------------------------------------------+---------------------------+
| Main field | Contains | Comments |
+=============================+====================================================+===========================+
-| :ref:`trex-global-field` | Must-have data on T-Rex run, | |
+| :ref:`trex-global-field` | Must-have data on TRex run, | |
| | mainly regarding Tx/Rx and packet drops | |
+-----------------------------+----------------------------------------------------+---------------------------+
| :ref:`tx-gen-field` | Data indicate the quality of the transmit process. | |
@@ -117,7 +117,7 @@ trex-global field .. _tx-gen-field:
tx-gen field
-~~~~~~~~~~~~~~
+~~~~~~~~~~~~
+-------------------+-------+-----------------------------------------------------------+
| Sub-key | Type | Meaning |
diff --git a/scripts/automation/trex_control_plane/doc/packet_generator/examples.rst b/scripts/automation/trex_control_plane/doc/packet_generator/examples.rst index f903feac..bff1ef7f 100755 --- a/scripts/automation/trex_control_plane/doc/packet_generator/examples.rst +++ b/scripts/automation/trex_control_plane/doc/packet_generator/examples.rst @@ -2,232 +2,4 @@ Packet Builder Usage Examples
=============================
-Whenever TRex is publishing live data, it uses JSON notation to describe the data-object.
-
-Each client may parse it diffrently, however this page will describe the values meaning when published by TRex server.
-
-
-Main Fields
------------
-
-Each TRex server-published JSON object contains data divided to main fields under which the actual data lays.
-
-These main fields are:
-
-+-----------------------------+----------------------------------------------------+---------------------------+
-| Main field | Contains | Comments |
-+=============================+====================================================+===========================+
-| :ref:`trex-global-field` | Must-have data on TRex run, | |
-| | mainly regarding Tx/Rx and packet drops | |
-+-----------------------------+----------------------------------------------------+---------------------------+
-| :ref:`tx-gen-field` | Data indicate the quality of the transmit process. | |
-| | In case histogram is zero it means that all packets| |
-| | were injected in the right time. | |
-+-----------------------------+----------------------------------------------------+---------------------------+
-| :ref:`trex-latecny-field` | Latency reports, containing latency data on | - Generated when latency |
-| | generated data and on response traffic | test is enabled (``l`` |
-| | | param) |
-| | | - *typo* on field key: |
-+-----------------------------+----------------------------------------------------+ will be fixed on next |
-| :ref:`trex-latecny-v2-field`| Extended latency information | release |
-+-----------------------------+----------------------------------------------------+---------------------------+
-
-
-Each of these fields contains keys for field general data (such as its name) and its actual data, which is always stored under the **"data"** key.
-
-For example, in order to access some trex-global data, the access path would look like::
-
- AllData -> trex-global -> data -> desired_info
-
-
-
-
-Detailed explanation
---------------------
-
-.. _trex-global-field:
-
-trex-global field
-~~~~~~~~~~~~~~~~~
-
-
-+--------------------------------+-------+-----------------------------------------------------------+
-| Sub-key | Type | Meaning |
-+================================+=======+===========================================================+
-| m_cpu_util | float | CPU utilization (0-100) |
-+--------------------------------+-------+-----------------------------------------------------------+
-| m_platform_factor | float | multiplier factor |
-+--------------------------------+-------+-----------------------------------------------------------+
-| m_tx_bps | float | total tx bit per second |
-+--------------------------------+-------+-----------------------------------------------------------+
-| m_rx_bps | float | total rx bit per second |
-+--------------------------------+-------+-----------------------------------------------------------+
-| m_tx_pps | float | total tx packet per second |
-+--------------------------------+-------+-----------------------------------------------------------+
-| m_tx_cps | float | total tx connection per second |
-+--------------------------------+-------+-----------------------------------------------------------+
-| m_tx_expected_cps | float | expected tx connection per second |
-+--------------------------------+-------+-----------------------------------------------------------+
-| m_tx_expected_pps | float | expected tx packet per second |
-+--------------------------------+-------+-----------------------------------------------------------+
-| m_tx_expected_bps | float | expected tx bit per second |
-+--------------------------------+-------+-----------------------------------------------------------+
-| m_rx_drop_bps | float | drop rate in bit per second |
-+--------------------------------+-------+-----------------------------------------------------------+
-| m_active_flows | float | active trex flows |
-+--------------------------------+-------+-----------------------------------------------------------+
-| m_open_flows | float | open trex flows from startup (monotonically incrementing) |
-+--------------------------------+-------+-----------------------------------------------------------+
-| m_total_tx_pkts | int | total tx in packets |
-+--------------------------------+-------+-----------------------------------------------------------+
-| m_total_rx_pkts | int | total rx in packets |
-+--------------------------------+-------+-----------------------------------------------------------+
-| m_total_tx_bytes | int | total tx in bytes |
-+--------------------------------+-------+-----------------------------------------------------------+
-| m_total_rx_bytes | int | total rx in bytes |
-+--------------------------------+-------+-----------------------------------------------------------+
-| opackets-# | int | output packets (per interface) |
-+--------------------------------+-------+-----------------------------------------------------------+
-| obytes-# | int | output bytes (per interface) |
-+--------------------------------+-------+-----------------------------------------------------------+
-| ipackets-# | int | input packet (per interface) |
-+--------------------------------+-------+-----------------------------------------------------------+
-| ibytes-# | int | input bytes (per interface) |
-+--------------------------------+-------+-----------------------------------------------------------+
-| ierrors-# | int | input errors (per interface) |
-+--------------------------------+-------+-----------------------------------------------------------+
-| oerrors-# | int | input errors (per interface) |
-+--------------------------------+-------+-----------------------------------------------------------+
-| m_total_tx_bps-# | float | total transmitted data in bit per second |
-+--------------------------------+-------+-----------------------------------------------------------+
-| unknown | int | |
-+--------------------------------+-------+-----------------------------------------------------------+
-| m_total_nat_learn_error [#f1]_ | int | |
-+--------------------------------+-------+-----------------------------------------------------------+
-| m_total_nat_active [#f2]_ | int | |
-+--------------------------------+-------+-----------------------------------------------------------+
-| m_total_nat_no_fid [#f2]_ | int | |
-+--------------------------------+-------+-----------------------------------------------------------+
-| m_total_nat_time_out [#f2]_ | int | |
-+--------------------------------+-------+-----------------------------------------------------------+
-| m_total_nat_open [#f2]_ | int | |
-+--------------------------------+-------+-----------------------------------------------------------+
-
-
-.. _tx-gen-field:
-
-tx-gen field
-~~~~~~~~~~~~~~
-
-+-------------------+-------+-----------------------------------------------------------+
-| Sub-key | Type | Meaning |
-+===================+=======+===========================================================+
-| realtime-hist | dict | histogram of transmission. See extended information about |
-| | | histogram object under :ref:`histogram-object-fields`. |
-| | | The attribute analyzed is time packet has been sent |
-| | | before/after it was intended to be |
-+-------------------+-------+-----------------------------------------------------------+
-| unknown | int | |
-+-------------------+-------+-----------------------------------------------------------+
-
-.. _trex-latecny-field:
-
-trex-latecny field
-~~~~~~~~~~~~~~~~~~
-
-+---------+-------+---------------------------------------------------------+
-| Sub-key | Type | Meaning |
-+=========+=======+=========================================================+
-| avg-# | float | average latency in usec (per interface) |
-+---------+-------+---------------------------------------------------------+
-| max-# | float | max latency in usec from the test start (per interface) |
-+---------+-------+---------------------------------------------------------+
-| c-max-# | float | max in the last 1 sec window (per interface) |
-+---------+-------+---------------------------------------------------------+
-| error-# | float | errors in latency packets (per interface) |
-+---------+-------+---------------------------------------------------------+
-| unknown | int | |
-+---------+-------+---------------------------------------------------------+
-
-.. _trex-latecny-v2-field:
-
-trex-latecny-v2 field
-~~~~~~~~~~~~~~~~~~~~~
-
-+--------------------------------------+-------+--------------------------------------+
-| Sub-key | Type | Meaning |
-+======================================+=======+======================================+
-| cpu_util | float | rx thread cpu % (this is not trex DP |
-| | | threads cpu%%) |
-+--------------------------------------+-------+--------------------------------------+
-| port-# | | Containing per interface |
-| | dict | information. See extended |
-| | | information under ``port-# -> |
-| | | key_name -> sub_key`` |
-+--------------------------------------+-------+--------------------------------------+
-| port-#->hist | dict | histogram of latency. See extended |
-| | | information about histogram object |
-| | | under :ref:`histogram-object-fields`.|
-+--------------------------------------+-------+--------------------------------------+
-| port-#->stats | | Containing per interface |
-| | dict | information. See extended |
-| | | information under ``port-# -> |
-| | | key_name -> sub_key`` |
-+--------------------------------------+-------+--------------------------------------+
-| port-#->stats->m_tx_pkt_ok | int | total of try sent packets |
-+--------------------------------------+-------+--------------------------------------+
-| port-#->stats->m_pkt_ok | int | total of packets sent from hardware |
-+--------------------------------------+-------+--------------------------------------+
-| port-#->stats->m_no_magic | int | rx error with no magic |
-+--------------------------------------+-------+--------------------------------------+
-| port-#->stats->m_no_id | int | rx errors with no id |
-+--------------------------------------+-------+--------------------------------------+
-| port-#->stats->m_seq_error | int | error in seq number |
-+--------------------------------------+-------+--------------------------------------+
-| port-#->stats->m_length_error | int | |
-+--------------------------------------+-------+--------------------------------------+
-| port-#->stats->m_rx_check | int | packets tested in rx |
-+--------------------------------------+-------+--------------------------------------+
-| unknown | int | |
-+--------------------------------------+-------+--------------------------------------+
-
-
-
-.. _histogram-object-fields:
-
-Histogram object fields
-~~~~~~~~~~~~~~~~~~~~~~~
-
-The histogram object is being used in number of place throughout the JSON object.
-The following section describes its fields in detail.
-
-
-+-----------+-------+-----------------------------------------------------------------------------------+
-| Sub-key | Type | Meaning |
-+===========+=======+===================================================================================+
-| min_usec | int | min attribute value in usec. pkt with latency less than this value is not counted |
-+-----------+-------+-----------------------------------------------------------------------------------+
-| max_usec | int | max attribute value in usec |
-+-----------+-------+-----------------------------------------------------------------------------------+
-| high_cnt | int | how many packets on which its attribute > min_usec |
-+-----------+-------+-----------------------------------------------------------------------------------+
-| cnt | int | total packets from test startup |
-+-----------+-------+-----------------------------------------------------------------------------------+
-| s_avg | float | average value from test startup |
-+-----------+-------+-----------------------------------------------------------------------------------+
-| histogram | | histogram of relevant object by the following keys: |
-| | array | - key: value in usec |
-| | | - val: number of packets |
-+-----------+-------+-----------------------------------------------------------------------------------+
-
-
-Access Examples
----------------
-
-
-
-.. rubric:: Footnotes
-
-.. [#f1] Available only in NAT and NAT learning operation (``learn`` and ``learn-verify`` flags)
-
-.. [#f2] Available only in NAT operation (``learn`` flag)
\ No newline at end of file +Here I'll add usage examples, very similar to those I added to RPC document
\ No newline at end of file diff --git a/scripts/automation/trex_control_plane/doc/packet_generator/stream_export.rst b/scripts/automation/trex_control_plane/doc/packet_generator/stream_export.rst index 21efbee9..eb639f7c 100755 --- a/scripts/automation/trex_control_plane/doc/packet_generator/stream_export.rst +++ b/scripts/automation/trex_control_plane/doc/packet_generator/stream_export.rst @@ -12,9 +12,9 @@ The TRex Packet Builder module supports (using ___ method) the export of built s Guidelines
----------
-1. The YAML file can either contain Byte representation of the packet of refer to a .pcap file that conatains it.
+1. The YAML file can either contain Byte representation of the packet of refer to a .pcap file that contains it.
2. The YAML file is similar as much as possible to the `add_stream method <http://trex-tgn.cisco.com/trex/doc/trex_rpc_server_spec.html#_add_stream>`_ of TRex RPC server spec, which defines the raw interaction with TRex server.
-3. Only packet binary data and VM instructinos are to be saved. Any meta-data packet builder module used while creating the packet will be stripped out.
+3. Only packet binary data and VM instructions are to be saved. Any meta-data packet builder module used while creating the packet will be stripped out.
Export Format
-------------
@@ -26,4 +26,4 @@ Export Format Example
-------
-The following files snapshot represents each of the options.
+The following files snapshot represents each of the options (Binary/pcap) for the very same HTTP GET request packet.
diff --git a/scripts/automation/trex_control_plane/examples/client_interactive_example.py b/scripts/automation/trex_control_plane/examples/client_interactive_example.py index 05028463..9ee28898 100755 --- a/scripts/automation/trex_control_plane/examples/client_interactive_example.py +++ b/scripts/automation/trex_control_plane/examples/client_interactive_example.py @@ -15,7 +15,7 @@ import errno class InteractiveTRexClient(cmd.Cmd): - intro = termstyle.green("\nInteractive shell to play with Cisco's T-Rex API.\nType help to view available pre-defined scenarios\n(c) All rights reserved.\n") + intro = termstyle.green("\nInteractive shell to play with Cisco's TRex API.\nType help to view available pre-defined scenarios\n(c) All rights reserved.\n") prompt = '> ' def __init__(self, trex_host, max_history_size = 100, trex_port = 8090, verbose_mode = False ): @@ -33,45 +33,45 @@ class InteractiveTRexClient(cmd.Cmd): def do_push_files (self, filepaths): - """Pushes a custom file to be stored locally on T-Rex server.\nPush multiple files by spefiying their path separated by ' ' (space).""" + """Pushes a custom file to be stored locally on TRex server.\nPush multiple files by spefiying their path separated by ' ' (space).""" try: filepaths = filepaths.split(' ') - print termstyle.green("*** Starting pushing files ({trex_files}) to T-Rex. ***".format (trex_files = ', '.join(filepaths)) ) + print termstyle.green("*** Starting pushing files ({trex_files}) to TRex. ***".format (trex_files = ', '.join(filepaths)) ) ret_val = self.trex.push_files(filepaths) if ret_val: - print termstyle.green("*** End of T-Rex push_files method (success) ***") + print termstyle.green("*** End of TRex push_files method (success) ***") else: - print termstyle.magenta("*** End of T-Rex push_files method (failed) ***") + print termstyle.magenta("*** End of TRex push_files method (failed) ***") except IOError as inst: print termstyle.magenta(inst) def do_show_default_run_params(self,line): - """Outputs the default T-Rex running parameters""" + """Outputs the default TRex running parameters""" pprint(self.DEFAULT_RUN_PARAMS) - print termstyle.green("*** End of default T-Rex running parameters ***") + print termstyle.green("*** End of default TRex running parameters ***") def do_show_run_params(self,line): - """Outputs the currently configured T-Rex running parameters""" + """Outputs the currently configured TRex running parameters""" pprint(self.run_params) - print termstyle.green("*** End of T-Rex running parameters ***") + print termstyle.green("*** End of TRex running parameters ***") def do_update_run_params(self, json_str): - """Updates provided parameters on T-Rex running configuration. Provide using JSON string""" + """Updates provided parameters on TRex running configuration. Provide using JSON string""" if json_str: try: upd_params = self.decoder.decode(json_str) self.run_params.update(upd_params) - print termstyle.green("*** End of T-Rex parameters update ***") + print termstyle.green("*** End of TRex parameters update ***") except ValueError as inst: print termstyle.magenta("Provided illegal JSON string. Please try again.\n[", inst,"]") else: print termstyle.magenta("JSON configuration string is missing. Please try again.") def do_show_status (self, line): - """Prompts T-Rex current status""" + """Prompts TRex current status""" print self.trex.get_running_status() - print termstyle.green("*** End of T-Rex status prompt ***") + print termstyle.green("*** End of TRex status prompt ***") def do_show_trex_files_path (self, line): """Prompts the local path in which files are stored when pushed to t-rex server from client""" @@ -79,43 +79,43 @@ class InteractiveTRexClient(cmd.Cmd): print termstyle.green("*** End of trex_files_path prompt ***") def do_show_reservation_status (self, line): - """Prompts if T-Rex is currently reserved or not""" + """Prompts if TRex is currently reserved or not""" if self.trex.is_reserved(): - print "T-Rex is reserved" + print "TRex is reserved" else: - print "T-Rex is NOT reserved" + print "TRex is NOT reserved" print termstyle.green("*** End of reservation status prompt ***") def do_reserve_trex (self, user): - """Reserves the usage of T-Rex to a certain user""" + """Reserves the usage of TRex to a certain user""" try: if not user: ret = self.trex.reserve_trex() else: ret = self.trex.reserve_trex(user.split(' ')[0]) - print termstyle.green("*** T-Rex reserved successfully ***") + print termstyle.green("*** TRex reserved successfully ***") except TRexException as inst: print termstyle.red(inst) def do_cancel_reservation (self, user): - """Cancels a current reservation of T-Rex to a certain user""" + """Cancels a current reservation of TRex to a certain user""" try: if not user: ret = self.trex.cancel_reservation() else: ret = self.trex.cancel_reservation(user.split(' ')[0]) - print termstyle.green("*** T-Rex reservation canceled successfully ***") + print termstyle.green("*** TRex reservation canceled successfully ***") except TRexException as inst: print termstyle.red(inst) def do_restore_run_default (self, line): - """Restores original T-Rex running configuration""" + """Restores original TRex running configuration""" self.run_params = dict(self.DEFAULT_RUN_PARAMS) print termstyle.green("*** End of restoring default run parameters ***") def do_run_until_finish (self, sample_rate): - """Starts T-Rex and sample server until run is done.""" - print termstyle.green("*** Starting T-Rex run_until_finish scenario ***") + """Starts TRex and sample server until run is done.""" + print termstyle.green("*** Starting TRex run_until_finish scenario ***") if not sample_rate: # use default sample rate if not passed sample_rate = 5 @@ -123,15 +123,15 @@ class InteractiveTRexClient(cmd.Cmd): sample_rate = int(sample_rate) ret = self.trex.start_trex(**self.run_params) self.trex.sample_to_run_finish(sample_rate) - print termstyle.green("*** End of T-Rex run ***") + print termstyle.green("*** End of TRex run ***") except ValueError as inst: print termstyle.magenta("Provided illegal sample rate value. Please try again.\n[", inst,"]") except TRexException as inst: print termstyle.red(inst) def do_run_and_poll (self, sample_rate): - """Starts T-Rex and sample server manually until run is done.""" - print termstyle.green("*** Starting T-Rex run and manually poll scenario ***") + """Starts TRex and sample server manually until run is done.""" + print termstyle.green("*** Starting TRex run and manually poll scenario ***") if not sample_rate: # use default sample rate if not passed sample_rate = 5 try: @@ -145,7 +145,7 @@ class InteractiveTRexClient(cmd.Cmd): # do WHATEVER here time.sleep(sample_rate) - print termstyle.green("*** End of T-Rex run ***") + print termstyle.green("*** End of TRex run ***") except ValueError as inst: print termstyle.magenta("Provided illegal sample rate value. Please try again.\n[", inst,"]") except TRexException as inst: @@ -153,8 +153,8 @@ class InteractiveTRexClient(cmd.Cmd): def do_run_until_condition (self, sample_rate): - """Starts T-Rex and sample server until condition is satisfied.""" - print termstyle.green("*** Starting T-Rex run until condition is satisfied scenario ***") + """Starts TRex and sample server until condition is satisfied.""" + print termstyle.green("*** Starting TRex run until condition is satisfied scenario ***") def condition (result_obj): return result_obj.get_current_tx_rate()['m_tx_pps'] > 200000 @@ -166,55 +166,55 @@ class InteractiveTRexClient(cmd.Cmd): ret = self.trex.start_trex(**self.run_params) ret_val = self.trex.sample_until_condition(condition, sample_rate) print ret_val - print termstyle.green("*** End of T-Rex run ***") + print termstyle.green("*** End of TRex run ***") except ValueError as inst: print termstyle.magenta("Provided illegal sample rate value. Please try again.\n[", inst,"]") except TRexException as inst: print termstyle.red(inst) def do_start_and_return (self, line): - """Start T-Rex run and once in 'Running' mode, return to cmd prompt""" - print termstyle.green("*** Starting T-Rex run, wait until in 'Running' state ***") + """Start TRex run and once in 'Running' mode, return to cmd prompt""" + print termstyle.green("*** Starting TRex run, wait until in 'Running' state ***") try: ret = self.trex.start_trex(**self.run_params) - print termstyle.green("*** End of scenario (T-Rex is probably still running!) ***") + print termstyle.green("*** End of scenario (TRex is probably still running!) ***") except TRexException as inst: print termstyle.red(inst) def do_poll_once (self, line): - """Performs a single poll of T-Rex current data dump (if T-Rex is running) and prompts and short version of latest result_obj""" - print termstyle.green("*** Trying T-Rex single poll ***") + """Performs a single poll of TRex current data dump (if TRex is running) and prompts and short version of latest result_obj""" + print termstyle.green("*** Trying TRex single poll ***") try: last_res = dict() if self.trex.is_running(dump_out = last_res): obj = self.trex.get_result_obj() print obj else: - print termstyle.magenta("T-Rex isn't currently running.") - print termstyle.green("*** End of scenario (T-Rex is posssibly still running!) ***") + print termstyle.magenta("TRex isn't currently running.") + print termstyle.green("*** End of scenario (TRex is posssibly still running!) ***") except TRexException as inst: print termstyle.red(inst) def do_stop_trex (self, line): - """Try to stop T-Rex run (if T-Rex is currently running)""" - print termstyle.green("*** Starting T-Rex termination ***") + """Try to stop TRex run (if TRex is currently running)""" + print termstyle.green("*** Starting TRex termination ***") try: ret = self.trex.stop_trex() - print termstyle.green("*** End of scenario (T-Rex is not running now) ***") + print termstyle.green("*** End of scenario (TRex is not running now) ***") except TRexException as inst: print termstyle.red(inst) def do_kill_indiscriminately (self, line): - """Force killing of running T-Rex process (if exists) on the server.""" - print termstyle.green("*** Starting T-Rex termination ***") + """Force killing of running TRex process (if exists) on the server.""" + print termstyle.green("*** Starting TRex termination ***") ret = self.trex.force_kill() if ret: - print termstyle.green("*** End of scenario (T-Rex is not running now) ***") + print termstyle.green("*** End of scenario (TRex is not running now) ***") elif ret is None: - print termstyle.magenta("*** End of scenario (T-Rex termination aborted) ***") + print termstyle.magenta("*** End of scenario (TRex termination aborted) ***") else: - print termstyle.red("*** End of scenario (T-Rex termination failed) ***") + print termstyle.red("*** End of scenario (TRex termination failed) ***") def do_exit(self, arg): """Quits the application""" @@ -223,20 +223,20 @@ class InteractiveTRexClient(cmd.Cmd): if __name__ == "__main__": - parser = ArgumentParser(description = termstyle.cyan('Run T-Rex client API demos and scenarios.'), + parser = ArgumentParser(description = termstyle.cyan('Run TRex client API demos and scenarios.'), usage = """client_interactive_example [options]""" ) parser.add_argument('-v', '--version', action='version', version='%(prog)s 1.0 \t (C) Cisco Systems Inc.\n') parser.add_argument("-t", "--trex-host", required = True, dest="trex_host", - action="store", help="Specify the hostname or ip to connect with T-Rex server.", + action="store", help="Specify the hostname or ip to connect with TRex server.", metavar="HOST" ) parser.add_argument("-p", "--trex-port", type=int, default = 8090, metavar="PORT", dest="trex_port", - help="Select port on which the T-Rex server listens. Default port is 8090.", action="store") + help="Select port on which the TRex server listens. Default port is 8090.", action="store") parser.add_argument("-m", "--maxhist", type=int, default = 100, metavar="SIZE", dest="hist_size", help="Specify maximum history size saved at client side. Default size is 100.", action="store") parser.add_argument("--verbose", dest="verbose", - action="store_true", help="Switch ON verbose option at T-Rex client. Default is: OFF.", + action="store_true", help="Switch ON verbose option at TRex client. Default is: OFF.", default = False ) args = parser.parse_args() @@ -248,7 +248,7 @@ if __name__ == "__main__": exit(-1) except socket.error, e: if e.errno == errno.ECONNREFUSED: - raise socket.error(errno.ECONNREFUSED, "Connection from T-Rex server was terminated. Please make sure the server is up.") + raise socket.error(errno.ECONNREFUSED, "Connection from TRex server was terminated. Please make sure the server is up.") diff --git a/scripts/automation/trex_control_plane/examples/pkt_generation_for_trex.py b/scripts/automation/trex_control_plane/examples/pkt_generation_for_trex.py index 7e7f6139..acaa95d3 100755 --- a/scripts/automation/trex_control_plane/examples/pkt_generation_for_trex.py +++ b/scripts/automation/trex_control_plane/examples/pkt_generation_for_trex.py @@ -2,7 +2,7 @@ ###################################################################################### ### ### -### T-Rex end-to-end demo script, written by T-Rex dev-team ### +### TRex end-to-end demo script, written by TRex dev-team ### ### THIS SCRIPT ASSUMES PyYaml and Scapy INSTALLED ON PYTHON'S RUNNING MACHINE ### ### (for any question please contact trex-dev team @ trex-dev@cisco.com) ### ### ### @@ -33,13 +33,13 @@ def pkts_to_pcap (pcap_filename, packets): def main (args): - # instantiate T-Rex client + # instantiate TRex client trex = CTRexClient('trex-dan', verbose = args.verbose) if args.steps: print "\nNext step: .pcap generation." raw_input("Press Enter to continue...") - # generate T-Rex traffic. + # generate TRex traffic. pkts = generate_dns_packets('21.0.0.2', '22.0.0.12') # In this case - DNS traffic (request-response) print "\ngenerated traffic:" print "==================" @@ -50,7 +50,7 @@ def main (args): print "\nNext step: .yaml generation." raw_input("Press Enter to continue...") # Generate .yaml file that uses the generated .pcap file - trex_files_path = trex.get_trex_files_path() # fetch the path in which packets are saved on T-Rex server + trex_files_path = trex.get_trex_files_path() # fetch the path in which packets are saved on TRex server yaml_obj = CTRexYaml(trex_files_path) # instantiate CTRexYaml obj # set .yaml file parameters according to need and use @@ -65,12 +65,12 @@ def main (args): yaml_obj.dump() if args.steps: - print "\nNext step: run T-Rex with provided files." + print "\nNext step: run TRex with provided files." raw_input("Press Enter to continue...") # push all relevant files to server trex.push_files( yaml_obj.get_file_list() ) - print "\nStarting T-Rex..." + print "\nStarting TRex..." trex.start_trex(c = 2, m = 1.5, nc = True, @@ -80,8 +80,8 @@ def main (args): l = 1000) if args.verbose: - print "T-Rex state changed to 'Running'." - print "Sampling T-Rex in 0.2 samples/sec (single sample every 5 secs)" + print "TRex state changed to 'Running'." + print "Sampling TRex in 0.2 samples/sec (single sample every 5 secs)" last_res = dict() while trex.is_running(dump_out = last_res): @@ -92,14 +92,14 @@ def main (args): if __name__ == "__main__": - parser = ArgumentParser(description = 'Run T-Rex client API end-to-end example.', + parser = ArgumentParser(description = 'Run TRex client API end-to-end example.', usage = """pkt_generation_for_trex [options]""" ) parser.add_argument("-s", "--step-by-step", dest="steps", action="store_false", help="Switch OFF step-by-step script overview. Default is: ON.", default = True ) parser.add_argument("--verbose", dest="verbose", - action="store_true", help="Switch ON verbose option at T-Rex client. Default is: OFF.", + action="store_true", help="Switch ON verbose option at TRex client. Default is: OFF.", default = False ) args = parser.parse_args() main(args)
\ No newline at end of file diff --git a/scripts/automation/trex_control_plane/server/extended_daemon_runner.py b/scripts/automation/trex_control_plane/server/extended_daemon_runner.py index 1813ed48..734fa22e 100755 --- a/scripts/automation/trex_control_plane/server/extended_daemon_runner.py +++ b/scripts/automation/trex_control_plane/server/extended_daemon_runner.py @@ -97,9 +97,9 @@ class ExtendedDaemonRunner(runner.DaemonRunner): @staticmethod
def _show(self):
if self.pidfile.is_locked():
- print termstyle.red("T-Rex server daemon is running")
+ print termstyle.red("TRex server daemon is running")
else:
- print termstyle.red("T-Rex server daemon is NOT running")
+ print termstyle.red("TRex server daemon is NOT running")
def do_action(self):
self.__prevent_duplicate_runs()
diff --git a/scripts/automation/trex_control_plane/server/trex_daemon_server.py b/scripts/automation/trex_control_plane/server/trex_daemon_server.py index 5032423a..ec07cb8a 100755 --- a/scripts/automation/trex_control_plane/server/trex_daemon_server.py +++ b/scripts/automation/trex_control_plane/server/trex_daemon_server.py @@ -54,7 +54,7 @@ def main (): logger.addHandler(handler) except EnvironmentError, e: if e.errno == errno.EACCES: # catching permission denied error - print "Launching user must have sudo privileges in order to run T-Rex daemon.\nTerminating daemon process." + print "Launching user must have sudo privileges in order to run TRex daemon.\nTerminating daemon process." exit(-1) try: diff --git a/scripts/automation/trex_control_plane/server/trex_launch_thread.py b/scripts/automation/trex_control_plane/server/trex_launch_thread.py index b4be60a9..59c382ea 100755 --- a/scripts/automation/trex_control_plane/server/trex_launch_thread.py +++ b/scripts/automation/trex_control_plane/server/trex_launch_thread.py @@ -33,44 +33,44 @@ class AsynchronousTRexSession(threading.Thread): with open(os.devnull, 'w') as DEVNULL:
self.time_stamps['start'] = self.time_stamps['run_time'] = time.time()
self.session = subprocess.Popen("exec "+self.cmd, cwd = self.launch_path, shell=True, stdin = DEVNULL, stderr = subprocess.PIPE, preexec_fn=os.setsid)
- logger.info("T-Rex session initialized successfully, Parent process pid is {pid}.".format( pid = self.session.pid ))
+ logger.info("TRex session initialized successfully, Parent process pid is {pid}.".format( pid = self.session.pid ))
while self.session.poll() is None: # subprocess is NOT finished
time.sleep(0.5)
if self.stoprequest.is_set():
- logger.debug("Abort request received by handling thread. Terminating T-Rex session." )
+ logger.debug("Abort request received by handling thread. Terminating TRex session." )
os.killpg(self.session.pid, signal.SIGUSR1)
self.trexObj.set_status(TRexStatus.Idle)
- self.trexObj.set_verbose_status("T-Rex is Idle")
+ self.trexObj.set_verbose_status("TRex is Idle")
break
self.time_stamps['run_time'] = time.time() - self.time_stamps['start']
try:
if self.time_stamps['run_time'] < 5:
- logger.error("T-Rex run failed due to wrong input parameters, or due to reachability issues.")
- self.trexObj.set_verbose_status("T-Rex run failed due to wrong input parameters, or due to reachability issues.\n\nT-Rex command: {cmd}\n\nRun output:\n{output}".format(
+ logger.error("TRex run failed due to wrong input parameters, or due to readability issues.")
+ self.trexObj.set_verbose_status("TRex run failed due to wrong input parameters, or due to readability issues.\n\nTRex command: {cmd}\n\nRun output:\n{output}".format(
cmd = self.cmd, output = self.load_trex_output(self.export_path)))
self.trexObj.errcode = -11
elif (self.session.returncode is not None and self.session.returncode < 0) or ( (self.time_stamps['run_time'] < self.duration) and (not self.stoprequest.is_set()) ):
if (self.session.returncode is not None and self.session.returncode < 0):
- logger.debug("Failed T-Rex run due to session return code ({ret_code})".format( ret_code = self.session.returncode ) )
+ logger.debug("Failed TRex run due to session return code ({ret_code})".format( ret_code = self.session.returncode ) )
elif ( (self.time_stamps['run_time'] < self.duration) and not self.stoprequest.is_set()):
- logger.debug("Failed T-Rex run due to running time ({runtime}) combined with no-stopping request.".format( runtime = self.time_stamps['run_time'] ) )
+ logger.debug("Failed TRex run due to running time ({runtime}) combined with no-stopping request.".format( runtime = self.time_stamps['run_time'] ) )
- logger.warning("T-Rex run was terminated unexpectedly by outer process or by the hosting OS")
- self.trexObj.set_verbose_status("T-Rex run was terminated unexpectedly by outer process or by the hosting OS.\n\nRun output:\n{output}".format(
+ logger.warning("TRex run was terminated unexpectedly by outer process or by the hosting OS")
+ self.trexObj.set_verbose_status("TRex run was terminated unexpectedly by outer process or by the hosting OS.\n\nRun output:\n{output}".format(
output = self.load_trex_output(self.export_path)))
self.trexObj.errcode = -15
else:
- logger.info("T-Rex run session finished.")
- self.trexObj.set_verbose_status('T-Rex finished.')
+ logger.info("TRex run session finished.")
+ self.trexObj.set_verbose_status('TRex finished.')
self.trexObj.errcode = None
finally:
self.trexObj.set_status(TRexStatus.Idle)
logger.info("TRex running state changed to 'Idle'.")
self.trexObj.expect_trex.clear()
- logger.debug("Finished handling a single run of T-Rex.")
+ logger.debug("Finished handling a single run of TRex.")
self.trexObj.zmq_dump = None
def join (self, timeout = None):
diff --git a/scripts/automation/trex_control_plane/server/trex_server.py b/scripts/automation/trex_control_plane/server/trex_server.py index 35b2669a..1e5098fb 100755 --- a/scripts/automation/trex_control_plane/server/trex_server.py +++ b/scripts/automation/trex_control_plane/server/trex_server.py @@ -34,7 +34,7 @@ CCustomLogger.setup_custom_logger('TRexServer') logger = logging.getLogger('TRexServer') class CTRexServer(object): - """This class defines the server side of the RESTfull interaction with T-Rex""" + """This class defines the server side of the RESTfull interaction with TRex""" DEFAULT_TREX_PATH = '/auto/proj-pcube-b/apps/PL-b/tools/bp_sim2/v1.55/' #'/auto/proj-pcube-b/apps/PL-b/tools/nightly/trex_latest' TREX_START_CMD = './t-rex-64' DEFAULT_FILE_PATH = '/tmp/trex_files/' @@ -53,7 +53,7 @@ class CTRexServer(object): the port number on which trex's zmq module will interact with daemon server default value: 4500 - Instantiate a T-Rex client object, and connecting it to listening daemon-server + Instantiate a TRex client object, and connecting it to listening daemon-server """ self.TREX_PATH = os.path.abspath(os.path.dirname(trex_path+'/')) self.trex_files_path = os.path.abspath(os.path.dirname(trex_files_path+'/')) @@ -94,17 +94,17 @@ class CTRexServer(object): """This method fires up the daemon server based on initialized parameters of the class""" # initialize the server instance with given reasources try: - print "Firing up T-Rex REST daemon @ port {trex_port} ...\n".format( trex_port = self.trex_daemon_port ) - logger.info("Firing up T-Rex REST daemon @ port {trex_port} ...".format( trex_port = self.trex_daemon_port )) + print "Firing up TRex REST daemon @ port {trex_port} ...\n".format( trex_port = self.trex_daemon_port ) + logger.info("Firing up TRex REST daemon @ port {trex_port} ...".format( trex_port = self.trex_daemon_port )) logger.info("current working dir is: {0}".format(self.TREX_PATH) ) logger.info("current files dir is : {0}".format(self.trex_files_path) ) logger.debug("Starting TRex server. Registering methods to process.") self.server = SimpleJSONRPCServer( (self.trex_host, self.trex_daemon_port) ) except socket.error as e: if e.errno == errno.EADDRINUSE: - logger.error("T-Rex server requested address already in use. Aborting server launching.") - print "T-Rex server requested address already in use. Aborting server launching." - raise socket.error(errno.EADDRINUSE, "T-Rex daemon requested address already in use. Server launch aborted. Please make sure no other process is using the desired server properties.") + logger.error("TRex server requested address already in use. Aborting server launching.") + print "TRex server requested address already in use. Aborting server launching." + raise socket.error(errno.EADDRINUSE, "TRex daemon requested address already in use. Server launch aborted. Please make sure no other process is using the desired server properties.") # set further functionality and peripherals to server instance try: @@ -136,7 +136,7 @@ class CTRexServer(object): def stop_handler (self, signum, frame): logger.info("Daemon STOP request detected.") if self.is_running(): - # in case T-Rex process is currently running, stop it before terminating server process + # in case TRex process is currently running, stop it before terminating server process self.stop_trex(self.trex.get_seq()) sys.exit(0) @@ -163,25 +163,25 @@ class CTRexServer(object): def reserve_trex (self, user): if user == "": - logger.info("T-Rex reservation cannot apply to empty string user. Request denied.") - return Fault(-33, "T-Rex reservation cannot apply to empty string user. Request denied.") + logger.info("TRex reservation cannot apply to empty string user. Request denied.") + return Fault(-33, "TRex reservation cannot apply to empty string user. Request denied.") with self.start_lock: logger.info("Processing reserve_trex() command.") if self.is_reserved(): if user == self.__reservation['user']: # return True is the same user is asking and already has the resrvation - logger.info("the same user is asking and already has the resrvation. Re-reserving T-Rex.") + logger.info("the same user is asking and already has the resrvation. Re-reserving TRex.") return True - logger.info("T-Rex is already reserved to another user ({res_user}), cannot reserve to another user.".format( res_user = self.__reservation['user'] )) - return Fault(-33, "T-Rex is already reserved to another user ({res_user}). Please make sure T-Rex is free before reserving it.".format( + logger.info("TRex is already reserved to another user ({res_user}), cannot reserve to another user.".format( res_user = self.__reservation['user'] )) + return Fault(-33, "TRex is already reserved to another user ({res_user}). Please make sure TRex is free before reserving it.".format( res_user = self.__reservation['user']) ) # raise at client TRexInUseError elif self.trex.get_status() != TRexStatus.Idle: - logger.info("T-Rex is currently running, cannot reserve T-Rex unless in Idle state.") - return Fault(-13, 'T-Rex is currently running, cannot reserve T-Rex unless in Idle state. Please try again when T-Rex run finished.') # raise at client TRexInUseError + logger.info("TRex is currently running, cannot reserve TRex unless in Idle state.") + return Fault(-13, 'TRex is currently running, cannot reserve TRex unless in Idle state. Please try again when TRex run finished.') # raise at client TRexInUseError else: - logger.info("T-Rex is now reserved for user ({res_user}).".format( res_user = user )) + logger.info("TRex is now reserved for user ({res_user}).".format( res_user = user )) self.__reservation = {'user' : user, 'since' : time.ctime()} logger.debug("Reservation details: "+ str(self.__reservation)) return True @@ -191,15 +191,15 @@ class CTRexServer(object): logger.info("Processing cancel_reservation() command.") if self.is_reserved(): if self.__reservation['user'] == user: - logger.info("T-Rex reservation to {res_user} has been canceled successfully.".format(res_user = self.__reservation['user'])) + logger.info("TRex reservation to {res_user} has been canceled successfully.".format(res_user = self.__reservation['user'])) self.__reservation = None return True else: - logger.warning("T-Rex is reserved to different user than the provided one. Reservation wasn't canceled.") + logger.warning("TRex is reserved to different user than the provided one. Reservation wasn't canceled.") return Fault(-33, "Cancel reservation request is available to the user that holds the reservation. Request denied") # raise at client TRexRequestDenied else: - logger.info("T-Rex is not reserved to anyone. No need to cancel anything") + logger.info("TRex is not reserved to anyone. No need to cancel anything") assert(self.__reservation is None) return False @@ -208,21 +208,21 @@ class CTRexServer(object): with self.start_lock: logger.info("Processing start_trex() command.") if self.is_reserved(): - # check if this is not the user to which T-Rex is reserved + # check if this is not the user to which TRex is reserved if self.__reservation['user'] != user: - logger.info("T-Rex is reserved to another user ({res_user}). Only that user is allowed to initiate new runs.".format(res_user = self.__reservation['user'])) - return Fault(-33, "T-Rex is reserved to another user ({res_user}). Only that user is allowed to initiate new runs.".format(res_user = self.__reservation['user'])) # raise at client TRexRequestDenied + logger.info("TRex is reserved to another user ({res_user}). Only that user is allowed to initiate new runs.".format(res_user = self.__reservation['user'])) + return Fault(-33, "TRex is reserved to another user ({res_user}). Only that user is allowed to initiate new runs.".format(res_user = self.__reservation['user'])) # raise at client TRexRequestDenied elif self.trex.get_status() != TRexStatus.Idle: - logger.info("T-Rex is already taken, cannot create another run until done.") + logger.info("TRex is already taken, cannot create another run until done.") return Fault(-13, '') # raise at client TRexInUseError try: server_cmd_data = self.generate_run_cmd(**trex_cmd_options) self.zmq_monitor.first_dump = True self.trex.start_trex(self.TREX_PATH, server_cmd_data) - logger.info("T-Rex session has been successfully initiated.") + logger.info("TRex session has been successfully initiated.") if block_to_success: - # delay server response until T-Rex is at 'Running' state. + # delay server response until TRex is at 'Running' state. start_time = time.time() trex_state = None while (time.time() - start_time) < timeout : @@ -232,20 +232,20 @@ class CTRexServer(object): else: time.sleep(0.5) - # check for T-Rex run started normally + # check for TRex run started normally if trex_state == TRexStatus.Starting: # reached timeout - logger.warning("TimeoutError: T-Rex initiation outcome could not be obtained, since T-Rex stays at Starting state beyond defined timeout.") - return Fault(-12, 'TimeoutError: T-Rex initiation outcome could not be obtained, since T-Rex stays at Starting state beyond defined timeout.') # raise at client TRexWarning + logger.warning("TimeoutError: TRex initiation outcome could not be obtained, since TRex stays at Starting state beyond defined timeout.") + return Fault(-12, 'TimeoutError: TRex initiation outcome could not be obtained, since TRex stays at Starting state beyond defined timeout.') # raise at client TRexWarning elif trex_state == TRexStatus.Idle: return Fault(-11, self.trex.get_verbose_status()) # raise at client TRexError - # reach here only if T-Rex is at 'Running' state + # reach here only if TRex is at 'Running' state self.trex.gen_seq() return self.trex.get_seq() # return unique seq number to client except TypeError as e: - logger.error("T-Rex command generation failed, probably because either -f (traffic generation .yaml file) and -c (num of cores) was not specified correctly.\nReceived params: {params}".format( params = trex_cmd_options) ) - raise TypeError('T-Rex -f (traffic generation .yaml file) and -c (num of cores) must be specified.') + logger.error("TRex command generation failed, probably because either -f (traffic generation .yaml file) and -c (num of cores) was not specified correctly.\nReceived params: {params}".format( params = trex_cmd_options) ) + raise TypeError('TRex -f (traffic generation .yaml file) and -c (num of cores) must be specified.') def stop_trex(self, seq): @@ -262,11 +262,11 @@ class CTRexServer(object): return False def force_trex_kill (self): - logger.info("Processing force_trex_kill() command. --> Killing T-Rex session indiscriminately.") + logger.info("Processing force_trex_kill() command. --> Killing TRex session indiscriminately.") return self.trex.stop_trex() def wait_until_kickoff_finish (self, timeout = 40): - # block until T-Rex exits Starting state + # block until TRex exits Starting state logger.info("Processing wait_until_kickoff_finish() command.") trex_state = None start_time = time.time() @@ -274,7 +274,7 @@ class CTRexServer(object): trex_state = self.trex.get_status() if trex_state != TRexStatus.Starting: return - return Fault(-12, 'TimeoutError: T-Rex initiation outcome could not be obtained, since T-Rex stays at Starting state beyond defined timeout.') # raise at client TRexWarning + return Fault(-12, 'TimeoutError: TRex initiation outcome could not be obtained, since TRex stays at Starting state beyond defined timeout.') # raise at client TRexWarning def get_running_info (self): logger.info("Processing get_running_info() command.") @@ -283,7 +283,7 @@ class CTRexServer(object): def generate_run_cmd (self, f, d, iom = 0, export_path="/tmp/trex.txt", **kwargs): """ generate_run_cmd(self, trex_cmd_options, export_path) -> str - Generates a custom running command for the kick-off of the T-Rex traffic generator. + Generates a custom running command for the kick-off of the TRex traffic generator. Returns a tuple of command (string) and export path (string) to be issued on the trex server Parameters @@ -325,14 +325,14 @@ class CTRexServer(object): def __check_trex_path_validity(self): # check for executable existance if not os.path.exists(self.TREX_PATH+'/t-rex-64'): - print "The provided T-Rex path do not contain an executable T-Rex file.\nPlease check the path and retry." - logger.error("The provided T-Rex path do not contain an executable T-Rex file") + print "The provided TRex path do not contain an executable TRex file.\nPlease check the path and retry." + logger.error("The provided TRex path do not contain an executable TRex file") exit(-1) # check for executable permissions st = os.stat(self.TREX_PATH+'/t-rex-64') if not bool(st.st_mode & (stat.S_IXUSR ) ): - print "The provided T-Rex path do not contain an T-Rex file with execution privileges.\nPlease check the files permissions and retry." - logger.error("The provided T-Rex path do not contain an T-Rex file with execution privileges") + print "The provided TRex path do not contain an TRex file with execution privileges.\nPlease check the files permissions and retry." + logger.error("The provided TRex path do not contain an TRex file with execution privileges") exit(-1) else: return @@ -357,7 +357,7 @@ class CTRexServer(object): class CTRex(object): def __init__(self): self.status = TRexStatus.Idle - self.verbose_status = 'T-Rex is Idle' + self.verbose_status = 'TRex is Idle' self.errcode = None self.session = None self.zmq_monitor = None @@ -388,34 +388,34 @@ class CTRex(object): if self.status == TRexStatus.Running: return self.encoder.encode(self.zmq_dump) else: - logger.info("T-Rex isn't running. Running information isn't available.") + logger.info("TRex isn't running. Running information isn't available.") if self.status == TRexStatus.Idle: if self.errcode is not None: # some error occured - logger.info("T-Rex is in Idle state, with errors. returning fault") + logger.info("TRex is in Idle state, with errors. returning fault") return Fault(self.errcode, self.verbose_status) # raise at client relevant exception, depending on the reason the error occured else: - logger.info("T-Rex is in Idle state, no errors. returning {}") + logger.info("TRex is in Idle state, no errors. returning {}") return u'{}' - return Fault(-12, self.verbose_status) # raise at client TRexWarning, indicating T-Rex is back to Idle state or still in Starting state + return Fault(-12, self.verbose_status) # raise at client TRexWarning, indicating TRex is back to Idle state or still in Starting state def stop_trex(self): if self.status == TRexStatus.Idle: # t-rex isn't running, nothing to abort - logger.info("T-Rex isn't running. No need to stop anything.") - if self.errcode is not None: # some error occured, notify client despite T-Rex already stopped + logger.info("TRex isn't running. No need to stop anything.") + if self.errcode is not None: # some error occurred, notify client despite TRex already stopped return Fault(self.errcode, self.verbose_status) # raise at client relevant exception, depending on the reason the error occured return False else: # handle stopping t-rex's run self.session.join() - logger.info("T-Rex session has been successfully aborted.") + logger.info("TRex session has been successfully aborted.") return True def start_trex(self, trex_launch_path, trex_cmd): self.set_status(TRexStatus.Starting) logger.info("TRex running state changed to 'Starting'.") - self.set_verbose_status('T-Rex is starting (data is not available yet)') + self.set_verbose_status('TRex is starting (data is not available yet)') self.errcode = None self.session = AsynchronousTRexSession(self, trex_launch_path, trex_cmd) @@ -430,7 +430,7 @@ def generate_trex_parser (): default_path = os.path.abspath(os.path.join(outer_packages.CURRENT_PATH, os.pardir, os.pardir, os.pardir)) default_files_path = os.path.abspath(CTRexServer.DEFAULT_FILE_PATH) - parser = ArgumentParser(description = 'Run server application for T-Rex traffic generator', + parser = ArgumentParser(description = 'Run server application for TRex traffic generator', formatter_class = RawTextHelpFormatter, usage = """ trex_daemon_server [options] @@ -440,10 +440,10 @@ trex_daemon_server [options] parser.add_argument("-p", "--daemon-port", type=int, default = 8090, metavar="PORT", dest="daemon_port", help="Select port on which the daemon runs.\nDefault port is 8090.", action="store") parser.add_argument("-z", "--zmq-port", dest="zmq_port", type=int, - action="store", help="Select port on which the ZMQ module listens to T-Rex.\nDefault port is 4500.", metavar="PORT", + action="store", help="Select port on which the ZMQ module listens to TRex.\nDefault port is 4500.", metavar="PORT", default = 4500) parser.add_argument("-t", "--trex-path", dest="trex_path", - action="store", help="Specify the compiled T-Rex directory from which T-Rex would run.\nDefault path is: {def_path}.".format( def_path = default_path ), + action="store", help="Specify the compiled TRex directory from which TRex would run.\nDefault path is: {def_path}.".format( def_path = default_path ), metavar="PATH", default = default_path ) parser.add_argument("-f", "--files-path", dest="files_path", action="store", help="Specify a path to directory on which pushed files will be saved at.\nDefault path is: {def_path}.".format( def_path = default_files_path ), diff --git a/scripts/automation/trex_control_plane/server/zmq_monitor_thread.py b/scripts/automation/trex_control_plane/server/zmq_monitor_thread.py index 7a278af8..db9bf7da 100755 --- a/scripts/automation/trex_control_plane/server/zmq_monitor_thread.py +++ b/scripts/automation/trex_control_plane/server/zmq_monitor_thread.py @@ -22,7 +22,7 @@ class ZmqMonitorSession(threading.Thread): self.zmq_port = zmq_port
self.zmq_publisher = "tcp://localhost:{port}".format(port=self.zmq_port)
self.trexObj = trexObj
- self.expect_trex = self.trexObj.expect_trex # used to signal if T-Rex is expected to run and if data should be considered
+ self.expect_trex = self.trexObj.expect_trex # used to signal if TRex is expected to run and if data should be considered
self.decoder = JSONDecoder()
logger.info("ZMQ monitor initialization finished")
@@ -69,7 +69,7 @@ class ZmqMonitorSession(threading.Thread): # change TRexStatus from starting to Running once the first ZMQ dump is obtained and parsed successfully
self.first_dump = False
self.trexObj.set_status(TRexStatus.Running)
- self.trexObj.set_verbose_status("T-Rex is Running")
+ self.trexObj.set_verbose_status("TRex is Running")
logger.info("First ZMQ dump received and successfully parsed. TRex running state changed to 'Running'.")
|