diff options
author | imarom <imarom@cisco.com> | 2015-09-24 17:51:04 +0300 |
---|---|---|
committer | imarom <imarom@cisco.com> | 2015-09-24 17:51:04 +0300 |
commit | 1f90e4ed08414c8aa423693c4ee8fa84e7675230 (patch) | |
tree | c73335567839000807f8db5bf56c1163c068d457 | |
parent | 59e080559abe0895bf2f19b156c7245aa98f31cc (diff) |
some improvements to the console
-rw-r--r-- | scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py | 50 | ||||
-rw-r--r-- | scripts/automation/trex_control_plane/console/trex_console.py | 112 | ||||
-rw-r--r-- | src/rpc-server/commands/trex_rpc_cmd_general.cpp | 18 | ||||
-rw-r--r-- | src/stateless/trex_stateless.cpp | 10 | ||||
-rw-r--r-- | src/stateless/trex_stateless_api.h | 30 |
5 files changed, 192 insertions, 28 deletions
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 8b091b5e..db52d633 100644 --- a/scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py +++ b/scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py @@ -60,6 +60,7 @@ class JsonRpcClient(object): return rc + # pretty print for JSON def pretty_json (self, json_str, use_colors = True): pretty_str = json.dumps(json.loads(json_str), indent = 4, separators=(',', ': '), sort_keys = True) @@ -87,6 +88,7 @@ class JsonRpcClient(object): print "[verbose] " + msg + # batch messages def create_batch (self): return BatchMessage(self) @@ -114,6 +116,7 @@ class JsonRpcClient(object): return self.send_raw_msg(msg, block) + # low level send of string message def send_raw_msg (self, msg, block = False): self.verbose_msg("Sending Request To Server:\n\n" + self.pretty_json(msg) + "\n") @@ -268,9 +271,15 @@ class TrexStatelessClient(JsonRpcClient): return self.server_version def get_system_info (self): + if not self.system_info: + return {} + return self.system_info def get_supported_cmds(self): + if not self.supported_cmds: + return {} + return self.supported_cmds def get_port_count (self): @@ -279,10 +288,10 @@ class TrexStatelessClient(JsonRpcClient): return self.system_info["port_count"] - # refresh the client for transient data - def refresh (self): + # sync the client with all the server required data + def sync (self): - # get server versionrc, msg = self.get_supported_cmds() + # get server version rc, msg = self.invoke_rpc_method("get_version") if not rc: self.disconnect() @@ -313,7 +322,7 @@ class TrexStatelessClient(JsonRpcClient): if not rc: return rc, err - return self.refresh() + return self.sync() # take ownership over ports @@ -446,4 +455,35 @@ class TrexStatelessClient(JsonRpcClient): index += 2 - return snap
\ No newline at end of file + return snap + + # add stream + def add_stream (self, port_id, stream_id, isg, next_stream_id, packet): + if not port_id in self.get_owned_ports(): + return False, "Port {0} is not owned... please take ownership before adding streams".format(port_id) + + handler = self.port_handlers[port_id] + + stream = {} + stream['enabled'] = True + stream['self_start'] = True + stream['isg'] = isg + stream['next_stream_id'] = next_stream_id + stream['packet'] = {} + stream['packet']['binary'] = packet + stream['packet']['meta'] = "" + stream['vm'] = [] + stream['rx_stats'] = {} + stream['rx_stats']['enabled'] = False + + stream['mode'] = {} + stream['mode']['type'] = 'continuous' + stream['mode']['pps'] = 10.0 + + params = {} + params['handler'] = handler + params['stream'] = stream + params['port_id'] = port_id + params['stream_id'] = stream_id + + return self.invoke_rpc_method('add_stream', params = params) diff --git a/scripts/automation/trex_control_plane/console/trex_console.py b/scripts/automation/trex_control_plane/console/trex_console.py index 3aeab901..9bf92174 100644 --- a/scripts/automation/trex_control_plane/console/trex_console.py +++ b/scripts/automation/trex_control_plane/console/trex_console.py @@ -8,11 +8,96 @@ import random import string import sys +import tty, termios import trex_root_path + from client_utils.jsonrpc_client import TrexStatelessClient import trex_status +# + +def readch (choices = []): + + fd = sys.stdin.fileno() + old_settings = termios.tcgetattr(fd) + try: + tty.setraw(sys.stdin.fileno()) + while True: + ch = sys.stdin.read(1) + if (ord(ch) == 3) or (ord(ch) == 4): + return None + if ch in choices: + return ch + finally: + termios.tcsetattr(fd, termios.TCSADRAIN, old_settings) + + return None + +class YesNoMenu(object): + def __init__ (self, caption): + self.caption = caption + + def show (self): + print "{0}".format(self.caption) + sys.stdout.write("[Y/y/N/n] : ") + ch = readch(choices = ['y', 'Y', 'n', 'N']) + if ch == None: + return None + + print "\n" + if ch == 'y' or ch == 'Y': + return True + else: + return False + +# multi level cmd menu +class CmdMenu(object): + def __init__ (self): + self.menus = [] + + + def add_menu (self, caption, options): + menu = {} + menu['caption'] = caption + menu['options'] = options + self.menus.append(menu) + + def show (self): + cur_level = 0 + print "\n" + + selected_path = [] + for menu in self.menus: + # show all the options + print "{0}\n".format(menu['caption']) + for i, option in enumerate(menu['options']): + print "{0}. {1}".format(i + 1, option) + + #print "\nPlease select an option: " + + choices = range(0, len(menu['options'])) + choices = [ chr(x + 48) for x in choices] + + print "" + ch = readch(choices) + print "" + + if ch == None: + return None + + selected_path.append(int(ch) - 1) + + return selected_path + + +class AddStreamMenu(CmdMenu): + def __init__ (self): + super(AddStreamMenu, self).__init__() + self.add_menu('Please select type of stream', ['a', 'b', 'c']) + self.add_menu('Please select ISG', ['d', 'e', 'f']) + +# main console object class TrexConsole(cmd.Cmd): """Trex Console""" @@ -108,6 +193,13 @@ class TrexConsole(cmd.Cmd): def do_acquire (self, line, force = False): '''Acquire ports\n''' + # make sure that the user wants to acquire all + if line == "": + ask = YesNoMenu('Do you want to acquire all ports ? ') + rc = ask.show() + if rc == False: + return + port_list = self.parse_ports_from_line(line) if not port_list: return @@ -313,12 +405,24 @@ 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) + # adds a very simple stream + def do_add_simple_stream (self, line): + if line == "": + add_stream = AddStreamMenu() + add_stream.show() + return + params = line.split() + port_id = int(params[0]) + stream_id = int(params[1]) + + packet = [0xFF,0xFF,0xFF] + rc, msg = self.rpc_client.add_stream(port_id = port_id, stream_id = stream_id, isg = 1.1, next_stream_id = -1, packet = packet) + if rc: + print "\nServer Response:\n\n" + self.rpc_client.pretty_json(json.dumps(msg)) + "\n" + else: + print "\n*** " + msg + "\n" # aliasing do_exit = do_EOF = do_q = do_quit diff --git a/src/rpc-server/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/commands/trex_rpc_cmd_general.cpp index 0c9f2c49..940baf3d 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_general.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_general.cpp @@ -271,17 +271,17 @@ TrexRpcCmdGetPortStats::_run(const Json::Value ¶ms, Json::Value &result) { result["result"]["status"] = port->get_state_as_string(); - result["result"]["tx_bps"] = Json::Value::UInt64(port->get_port_stats().tx_bps); - result["result"]["tx_pps"] = Json::Value::UInt64(port->get_port_stats().tx_pps); - result["result"]["total_tx_pkts"] = Json::Value::UInt64(port->get_port_stats().total_tx_pkts); - result["result"]["total_tx_bytes"] = Json::Value::UInt64(port->get_port_stats().total_tx_bytes); + result["result"]["tx_bps"] = Json::Value::UInt64(port->get_port_stats().m_stats.tx_bps); + result["result"]["tx_pps"] = Json::Value::UInt64(port->get_port_stats().m_stats.tx_pps); + result["result"]["total_tx_pkts"] = Json::Value::UInt64(port->get_port_stats().m_stats.total_tx_pkts); + result["result"]["total_tx_bytes"] = Json::Value::UInt64(port->get_port_stats().m_stats.total_tx_bytes); - result["result"]["rx_bps"] = Json::Value::UInt64(port->get_port_stats().rx_bps); - result["result"]["rx_pps"] = Json::Value::UInt64(port->get_port_stats().rx_pps); - result["result"]["total_rx_pkts"] = Json::Value::UInt64(port->get_port_stats().total_rx_pkts); - result["result"]["total_rx_bytes"] = Json::Value::UInt64(port->get_port_stats().total_rx_bytes); + result["result"]["rx_bps"] = Json::Value::UInt64(port->get_port_stats().m_stats.rx_bps); + result["result"]["rx_pps"] = Json::Value::UInt64(port->get_port_stats().m_stats.rx_pps); + result["result"]["total_rx_pkts"] = Json::Value::UInt64(port->get_port_stats().m_stats.total_rx_pkts); + result["result"]["total_rx_bytes"] = Json::Value::UInt64(port->get_port_stats().m_stats.total_rx_bytes); - result["result"]["tx_rx_error"] = Json::Value::UInt64(port->get_port_stats().tx_rx_errors); + result["result"]["tx_rx_error"] = Json::Value::UInt64(port->get_port_stats().m_stats.tx_rx_errors); return (TREX_RPC_CMD_OK); } diff --git a/src/stateless/trex_stateless.cpp b/src/stateless/trex_stateless.cpp index 0eb96f05..3ec419ea 100644 --- a/src/stateless/trex_stateless.cpp +++ b/src/stateless/trex_stateless.cpp @@ -73,6 +73,15 @@ uint8_t TrexStateless::get_port_count() { return m_port_count; } + +/*************************** + * trex stateless port stats + * + **************************/ +TrexPortStats::TrexPortStats() { + m_stats = {0}; +} + /*************************** * trex stateless port * @@ -80,7 +89,6 @@ uint8_t TrexStateless::get_port_count() { TrexStatelessPort::TrexStatelessPort(uint8_t port_id) : m_port_id(port_id) { m_port_state = PORT_STATE_UP_IDLE; clear_owner(); - m_stats = {0}; } diff --git a/src/stateless/trex_stateless_api.h b/src/stateless/trex_stateless_api.h index 7a9080aa..ca093e03 100644 --- a/src/stateless/trex_stateless_api.h +++ b/src/stateless/trex_stateless_api.h @@ -42,14 +42,17 @@ public: }; /** - * describes a stateless port + * TRex stateless port stats * - * @author imarom (31-Aug-15) + * @author imarom (24-Sep-15) */ -class TrexStatelessPort { +class TrexPortStats { + public: + TrexPortStats(); - struct TrexPortStats { +public: + struct { uint64_t tx_pps; uint64_t tx_bps; uint64_t total_tx_pkts; @@ -61,7 +64,16 @@ public: uint64_t total_rx_bytes; uint64_t tx_rx_errors; - }; + } m_stats; +}; + +/** + * describes a stateless port + * + * @author imarom (31-Aug-15) + */ +class TrexStatelessPort { +public: /** * port state @@ -171,10 +183,10 @@ public: const TrexPortStats & get_port_stats(void) { /* scrabble */ - m_stats.tx_bps += 1 + rand() % 100; - m_stats.tx_pps += 1 + rand() % 10; - m_stats.total_tx_bytes += 1 + rand() % 10; - m_stats.total_tx_pkts += 1 + rand() % 5; + m_stats.m_stats.tx_bps += 1 + rand() % 100; + m_stats.m_stats.tx_pps += 1 + rand() % 10; + m_stats.m_stats.total_tx_bytes += 1 + rand() % 10; + m_stats.m_stats.total_tx_pkts += 1 + rand() % 5; return m_stats; } |