summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2015-09-24 17:51:04 +0300
committerimarom <imarom@cisco.com>2015-09-24 17:51:04 +0300
commit1f90e4ed08414c8aa423693c4ee8fa84e7675230 (patch)
treec73335567839000807f8db5bf56c1163c068d457
parent59e080559abe0895bf2f19b156c7245aa98f31cc (diff)
some improvements to the console
-rw-r--r--scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py50
-rw-r--r--scripts/automation/trex_control_plane/console/trex_console.py112
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_general.cpp18
-rw-r--r--src/stateless/trex_stateless.cpp10
-rw-r--r--src/stateless/trex_stateless_api.h30
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 &params, 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;
}