summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2015-12-03 06:07:20 -0500
committerimarom <imarom@cisco.com>2015-12-06 03:57:02 -0500
commita6af2a8e624c62d9a347215321c6562f28879d97 (patch)
treeb3a90eafc7930957235cdb10250daed09f1e9fda
parent15c30aa3b73c4f8714c2e3b4aab22a154f4a8fe9 (diff)
various fixes (each one is a minor one)
-rwxr-xr-xscripts/automation/trex_control_plane/client/trex_stateless_client.py112
-rwxr-xr-xscripts/automation/trex_control_plane/common/trex_streams.py3
-rwxr-xr-xscripts/automation/trex_control_plane/console/trex_console.py65
-rw-r--r--src/rpc-server/commands/trex_rpc_cmd_stream.cpp183
-rw-r--r--src/rpc-server/commands/trex_rpc_cmds.h1
-rw-r--r--src/rpc-server/trex_rpc_cmds_table.cpp3
-rw-r--r--src/stateless/cp/trex_stateless_port.cpp35
-rw-r--r--src/stateless/cp/trex_stateless_port.h25
-rw-r--r--src/stateless/cp/trex_streams_compiler.cpp2
-rw-r--r--src/stateless/cp/trex_streams_compiler.h1
10 files changed, 256 insertions, 174 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 4436be75..6082863e 100755
--- a/scripts/automation/trex_control_plane/client/trex_stateless_client.py
+++ b/scripts/automation/trex_control_plane/client/trex_stateless_client.py
@@ -414,6 +414,17 @@ class Port(object):
return self.ok()
+
+ def validate (self):
+ params = {"handler": self.handler,
+ "port_id": self.port_id}
+
+ rc, data = self.transmit("validate", params)
+ if not rc:
+ return self.err(data)
+
+ return self.ok()
+
################# events handler ######################
def async_event_port_stopped (self):
self.state = self.STATE_STREAMS
@@ -519,6 +530,11 @@ class CTRexStatelessClient(object):
def wrap(*args):
time1 = time.time()
ret = f(*args)
+
+ # don't want to print on error
+ if ret.bad():
+ return ret
+
delta = time.time() - time1
for unit in ['sec','ms','usec']:
@@ -842,6 +858,17 @@ class CTRexStatelessClient(object):
return rc
+ def validate (self, port_id_list = None):
+ port_id_list = self.__ports(port_id_list)
+
+ rc = RC()
+
+ for port_id in port_id_list:
+ rc.add(self.ports[port_id].validate())
+
+ return rc
+
+
def get_port_stats(self, port_id=None):
pass
@@ -962,19 +989,6 @@ class CTRexStatelessClient(object):
return RC_OK()
- def cmd_pause_line (self, line):
- '''Pause active traffic in specified ports on TRex\n'''
- parser = parsing_opts.gen_parser(self,
- "pause",
- self.cmd_stop_line.__doc__,
- parsing_opts.PORT_LIST_WITH_ALL)
-
- opts = parser.parse_args(line.split())
- if opts is None:
- return RC_ERR("bad command line paramters")
-
- return self.cmd_pause(opts.ports)
-
# resume cmd
def cmd_resume (self, port_id_list):
@@ -995,19 +1009,6 @@ class CTRexStatelessClient(object):
return RC_OK()
- def cmd_resume_line (self, line):
- '''Resume active traffic in specified ports on TRex\n'''
- parser = parsing_opts.gen_parser(self,
- "resume",
- self.cmd_stop_line.__doc__,
- parsing_opts.PORT_LIST_WITH_ALL)
-
- opts = parser.parse_args(line.split())
- if opts is None:
- return RC_ERR("bad command line paramters")
-
- return self.cmd_resume(opts.ports)
-
# start cmd
def cmd_start (self, port_id_list, stream_list, mult, force, duration):
@@ -1043,6 +1044,15 @@ class CTRexStatelessClient(object):
return RC_OK()
+
+ def cmd_validate (self, port_id_list):
+ rc = self.validate(port_id_list)
+ rc.annotate("Validating streams on port(s) {0}:".format(port_id_list))
+ if rc.bad():
+ return rc
+
+ return RC_OK()
+
############## High Level API With Parser ################
@timing
def cmd_start_line (self, line):
@@ -1126,7 +1136,53 @@ class CTRexStatelessClient(object):
def cmd_reset_line (self, line):
return self.cmd_reset()
-
+
+ @timing
+ def cmd_pause_line (self, line):
+ '''Pause active traffic in specified ports on TRex\n'''
+ parser = parsing_opts.gen_parser(self,
+ "pause",
+ self.cmd_stop_line.__doc__,
+ parsing_opts.PORT_LIST_WITH_ALL)
+
+ opts = parser.parse_args(line.split())
+ if opts is None:
+ return RC_ERR("bad command line paramters")
+
+ return self.cmd_pause(opts.ports)
+
+
+ @timing
+ def cmd_resume_line (self, line):
+ '''Resume active traffic in specified ports on TRex\n'''
+ parser = parsing_opts.gen_parser(self,
+ "resume",
+ self.cmd_stop_line.__doc__,
+ parsing_opts.PORT_LIST_WITH_ALL)
+
+ opts = parser.parse_args(line.split())
+ if opts is None:
+ return RC_ERR("bad command line paramters")
+
+ return self.cmd_resume(opts.ports)
+
+
+ @timing
+ def cmd_validate_line (self, line):
+ '''validates port(s) stream configuration\n'''
+
+ parser = parsing_opts.gen_parser(self,
+ "validate",
+ self.cmd_validate_line.__doc__,
+ parsing_opts.PORT_LIST_WITH_ALL)
+
+ opts = parser.parse_args(line.split())
+ if opts is None:
+ return RC_ERR("bad command line paramters")
+
+ return self.cmd_validate(opts.ports)
+
+
def cmd_exit_line (self, line):
print format_text("Exiting\n", 'bold')
# a way to exit
@@ -1262,5 +1318,3 @@ class CTRexStatelessClient(object):
if __name__ == "__main__":
pass
-
-
diff --git a/scripts/automation/trex_control_plane/common/trex_streams.py b/scripts/automation/trex_control_plane/common/trex_streams.py
index c2823445..89de7286 100755
--- a/scripts/automation/trex_control_plane/common/trex_streams.py
+++ b/scripts/automation/trex_control_plane/common/trex_streams.py
@@ -14,7 +14,7 @@ StreamPack = namedtuple('StreamPack', ['stream_id', 'stream'])
class CStreamList(object):
def __init__(self):
- self.streams_list = {}
+ self.streams_list = OrderedDict()
self.yaml_loader = CTRexYAMLLoader(os.path.join(os.path.dirname(os.path.realpath(__file__)),
"rpc_defaults.yaml"))
@@ -82,6 +82,7 @@ class CStreamList(object):
stream_ids = {}
for idx, stream_name in enumerate(self.streams_list):
stream_ids[stream_name] = idx
+
# next, iterate over the streams and transform them from working with names to ids.
# with that build a new dict with old stream_name as the key, and StreamPack as the stored value
compiled_streams = {}
diff --git a/scripts/automation/trex_control_plane/console/trex_console.py b/scripts/automation/trex_control_plane/console/trex_console.py
index be8fb70e..73f4f612 100755
--- a/scripts/automation/trex_control_plane/console/trex_console.py
+++ b/scripts/automation/trex_control_plane/console/trex_console.py
@@ -35,7 +35,7 @@ from common.text_opts import *
from client_utils.general_utils import user_input, get_current_user
import trex_status
import parsing_opts
-
+from functools import wraps
__version__ = "1.1"
@@ -128,6 +128,18 @@ class TRexConsole(TRexGeneralCmd):
################### internal section ########################
+ def verify_connected(f):
+ @wraps(f)
+ def wrap(*args):
+ inst = args[0]
+ if not inst.stateless_client.is_connected():
+ print format_text("\nNot connected to server\n", 'bold')
+ return
+
+ ret = f(*args)
+ return ret
+
+ return wrap
def get_console_identifier(self):
return "{context}_{server}".format(context=self.__class__.__name__,
@@ -207,13 +219,9 @@ class TRexConsole(TRexGeneralCmd):
####################### shell commands #######################
+ @verify_connected
def do_ping (self, line):
'''Ping the server\n'''
-
- if not self.stateless_client.is_connected():
- print format_text("\nNot connected to server\n", 'bold')
- return
-
rc = self.stateless_client.cmd_ping()
if rc.bad():
return
@@ -303,13 +311,10 @@ class TRexConsole(TRexGeneralCmd):
if (l > 2) and (s[l - 2] in file_flags):
return TRexConsole.tree_autocomplete(s[l - 1])
+ @verify_connected
def do_start(self, line):
'''Start selected traffic in specified port(s) on TRex\n'''
- if not self.stateless_client.is_connected():
- print format_text("\nNot connected to server\n", 'bold')
- return
-
self.stateless_client.cmd_start_line(line)
@@ -317,64 +322,57 @@ class TRexConsole(TRexGeneralCmd):
self.do_start("-h")
############# stop
+ @verify_connected
def do_stop(self, line):
'''stops port(s) transmitting traffic\n'''
- if not self.stateless_client.is_connected():
- print format_text("\nNot connected to server\n", 'bold')
- return
-
self.stateless_client.cmd_stop_line(line)
def help_stop(self):
self.do_stop("-h")
############# update
+ @verify_connected
def do_update(self, line):
'''update speed of port(s)currently transmitting traffic\n'''
- if not self.stateless_client.is_connected():
- print format_text("\nNot connected to server\n", 'bold')
- return
-
self.stateless_client.cmd_update_line(line)
def help_update (self):
self.do_update("-h")
############# pause
+ @verify_connected
def do_pause(self, line):
'''pause port(s) transmitting traffic\n'''
- if not self.stateless_client.is_connected():
- print format_text("\nNot connected to server\n", 'bold')
- return
-
self.stateless_client.cmd_pause_line(line)
############# resume
+ @verify_connected
def do_resume(self, line):
'''resume port(s) transmitting traffic\n'''
- if not self.stateless_client.is_connected():
- print format_text("\nNot connected to server\n", 'bold')
- return
-
self.stateless_client.cmd_resume_line(line)
########## reset
+ @verify_connected
def do_reset (self, line):
'''force stop all ports\n'''
- if not self.stateless_client.is_connected():
- print format_text("\nNot connected to server\n", 'bold')
- return
-
self.stateless_client.cmd_reset_line(line)
-
+
+ ######### validate
+ @verify_connected
+ def do_validate (self, line):
+ '''validates port(s) stream configuration\n'''
+
+ self.stateless_client.cmd_validate_line(line)
+
+
def help_events (self):
self.do_events("-h")
@@ -404,13 +402,10 @@ class TRexConsole(TRexGeneralCmd):
print format_text("\n\nEvent log was cleared\n\n")
# tui
+ @verify_connected
def do_tui (self, line):
'''Shows a graphical console\n'''
- if not self.stateless_client.is_connected():
- print format_text("\nNot connected to server\n", 'bold')
- return
-
self.do_verbose('off')
trex_status.show_trex_status(self.stateless_client)
diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
index 51df3159..1e8328dc 100644
--- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
+++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp
@@ -23,6 +23,7 @@ limitations under the License.
#include <trex_stream.h>
#include <trex_stateless.h>
#include <trex_stateless_port.h>
+#include <trex_streams_compiler.h>
#include <iostream>
@@ -52,7 +53,8 @@ static uint64_t str2num(const string &str) {
trex_rpc_cmd_rc_e
TrexRpcCmdAddStream::_run(const Json::Value &params, Json::Value &result) {
- uint8_t port_id = parse_int(params, "port_id", result);
+ uint8_t port_id = parse_port(params, result);
+
uint32_t stream_id = parse_int(params, "stream_id", result);
const Json::Value &section = parse_object(params, "stream", result);
@@ -296,15 +298,7 @@ TrexRpcCmdAddStream::validate_stream(const TrexStream *stream, Json::Value &resu
generate_execute_err(result, ss.str());
}
- /* port id should be between 0 and count - 1 */
- if (stream->m_port_id >= get_stateless_obj()->get_port_count()) {
- std::stringstream ss;
- ss << "invalid port id - should be between 0 and " << (int)get_stateless_obj()->get_port_count() - 1;
- delete stream;
- generate_execute_err(result, ss.str());
- }
-
- /* add the stream to the port's stream table */
+ /* add the stream to the port's stream table */
TrexStatelessPort * port = get_stateless_obj()->get_port_by_id(stream->m_port_id);
/* does such a stream exists ? */
@@ -323,17 +317,11 @@ TrexRpcCmdAddStream::validate_stream(const TrexStream *stream, Json::Value &resu
**************************/
trex_rpc_cmd_rc_e
TrexRpcCmdRemoveStream::_run(const Json::Value &params, Json::Value &result) {
- uint8_t port_id = parse_byte(params, "port_id", result);
- uint32_t stream_id = parse_int(params, "stream_id", result);
-
-
- if (port_id >= get_stateless_obj()->get_port_count()) {
- std::stringstream ss;
- ss << "invalid port id - should be between 0 and " << (int)get_stateless_obj()->get_port_count() - 1;
- generate_execute_err(result, ss.str());
- }
+ uint8_t port_id = parse_port(params, result);
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
+
+ uint32_t stream_id = parse_int(params, "stream_id", result);
TrexStream *stream = port->get_stream_by_id(stream_id);
if (!stream) {
@@ -362,14 +350,8 @@ TrexRpcCmdRemoveStream::_run(const Json::Value &params, Json::Value &result) {
**************************/
trex_rpc_cmd_rc_e
TrexRpcCmdRemoveAllStreams::_run(const Json::Value &params, Json::Value &result) {
- uint8_t port_id = parse_byte(params, "port_id", result);
-
- if (port_id >= get_stateless_obj()->get_port_count()) {
- std::stringstream ss;
- ss << "invalid port id - should be between 0 and " << (int)get_stateless_obj()->get_port_count() - 1;
- generate_execute_err(result, ss.str());
- }
+ uint8_t port_id = parse_port(params, result);
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
try {
@@ -393,27 +375,20 @@ trex_rpc_cmd_rc_e
TrexRpcCmdGetStreamList::_run(const Json::Value &params, Json::Value &result) {
std::vector<uint32_t> stream_list;
- uint8_t port_id = parse_byte(params, "port_id", result);
-
- if (port_id >= get_stateless_obj()->get_port_count()) {
- std::stringstream ss;
- ss << "invalid port id - should be between 0 and " << (int)get_stateless_obj()->get_port_count() - 1;
- generate_execute_err(result, ss.str());
- }
-
- TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
+ uint8_t port_id = parse_port(params, result);
+ TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
- port->get_id_list(stream_list);
+ port->get_id_list(stream_list);
- Json::Value json_list = Json::arrayValue;
+ Json::Value json_list = Json::arrayValue;
- for (auto stream_id : stream_list) {
- json_list.append(stream_id);
- }
+ for (auto stream_id : stream_list) {
+ json_list.append(stream_id);
+ }
- result["result"] = json_list;
+ result["result"] = json_list;
- return (TREX_RPC_CMD_OK);
+ return (TREX_RPC_CMD_OK);
}
/***************************
@@ -423,18 +398,13 @@ TrexRpcCmdGetStreamList::_run(const Json::Value &params, Json::Value &result) {
**************************/
trex_rpc_cmd_rc_e
TrexRpcCmdGetStream::_run(const Json::Value &params, Json::Value &result) {
- uint8_t port_id = parse_byte(params, "port_id", result);
- bool get_pkt = parse_bool(params, "get_pkt", result);
- uint32_t stream_id = parse_int(params, "stream_id", result);
-
- if (port_id >= get_stateless_obj()->get_port_count()) {
- std::stringstream ss;
- ss << "invalid port id - should be between 0 and " << (int)get_stateless_obj()->get_port_count() - 1;
- generate_execute_err(result, ss.str());
- }
+ uint8_t port_id = parse_port(params, result);
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
+ bool get_pkt = parse_bool(params, "get_pkt", result);
+ uint32_t stream_id = parse_int(params, "stream_id", result);
+
TrexStream *stream = port->get_stream_by_id(stream_id);
if (!stream) {
@@ -462,17 +432,11 @@ TrexRpcCmdGetStream::_run(const Json::Value &params, Json::Value &result) {
trex_rpc_cmd_rc_e
TrexRpcCmdStartTraffic::_run(const Json::Value &params, Json::Value &result) {
- uint8_t port_id = parse_byte(params, "port_id", result);
- double duration = parse_double(params, "duration", result);
-
- if (port_id >= get_stateless_obj()->get_port_count()) {
- std::stringstream ss;
- ss << "invalid port id - should be between 0 and " << (int)get_stateless_obj()->get_port_count() - 1;
- generate_execute_err(result, ss.str());
- }
-
+ uint8_t port_id = parse_port(params, result);
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
+ double duration = parse_double(params, "duration", result);
+
/* multiplier */
const Json::Value &mul_obj = parse_object(params, "mul", result);
@@ -504,14 +468,8 @@ TrexRpcCmdStartTraffic::_run(const Json::Value &params, Json::Value &result) {
**************************/
trex_rpc_cmd_rc_e
TrexRpcCmdStopTraffic::_run(const Json::Value &params, Json::Value &result) {
- uint8_t port_id = parse_byte(params, "port_id", result);
-
- if (port_id >= get_stateless_obj()->get_port_count()) {
- std::stringstream ss;
- ss << "invalid port id - should be between 0 and " << (int)get_stateless_obj()->get_port_count() - 1;
- generate_execute_err(result, ss.str());
- }
+ uint8_t port_id = parse_port(params, result);
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
try {
@@ -531,17 +489,12 @@ TrexRpcCmdStopTraffic::_run(const Json::Value &params, Json::Value &result) {
**************************/
trex_rpc_cmd_rc_e
TrexRpcCmdGetAllStreams::_run(const Json::Value &params, Json::Value &result) {
- uint8_t port_id = parse_byte(params, "port_id", result);
- bool get_pkt = parse_bool(params, "get_pkt", result);
-
- if (port_id >= get_stateless_obj()->get_port_count()) {
- std::stringstream ss;
- ss << "invalid port id - should be between 0 and " << (int)get_stateless_obj()->get_port_count() - 1;
- generate_execute_err(result, ss.str());
- }
-
+
+ uint8_t port_id = parse_port(params, result);
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
+ bool get_pkt = parse_bool(params, "get_pkt", result);
+
std::vector <TrexStream *> streams;
port->get_object_list(streams);
@@ -573,14 +526,7 @@ TrexRpcCmdGetAllStreams::_run(const Json::Value &params, Json::Value &result) {
trex_rpc_cmd_rc_e
TrexRpcCmdPauseTraffic::_run(const Json::Value &params, Json::Value &result) {
- uint8_t port_id = parse_byte(params, "port_id", result);
-
- if (port_id >= get_stateless_obj()->get_port_count()) {
- std::stringstream ss;
- ss << "invalid port id - should be between 0 and " << (int)get_stateless_obj()->get_port_count() - 1;
- generate_execute_err(result, ss.str());
- }
-
+ uint8_t port_id = parse_port(params, result);
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
try {
@@ -601,14 +547,7 @@ TrexRpcCmdPauseTraffic::_run(const Json::Value &params, Json::Value &result) {
trex_rpc_cmd_rc_e
TrexRpcCmdResumeTraffic::_run(const Json::Value &params, Json::Value &result) {
- uint8_t port_id = parse_byte(params, "port_id", result);
-
- if (port_id >= get_stateless_obj()->get_port_count()) {
- std::stringstream ss;
- ss << "invalid port id - should be between 0 and " << (int)get_stateless_obj()->get_port_count() - 1;
- generate_execute_err(result, ss.str());
- }
-
+ uint8_t port_id = parse_port(params, result);
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
try {
@@ -629,14 +568,7 @@ TrexRpcCmdResumeTraffic::_run(const Json::Value &params, Json::Value &result) {
trex_rpc_cmd_rc_e
TrexRpcCmdUpdateTraffic::_run(const Json::Value &params, Json::Value &result) {
- uint8_t port_id = parse_byte(params, "port_id", result);
-
- if (port_id >= get_stateless_obj()->get_port_count()) {
- std::stringstream ss;
- ss << "invalid port id - should be between 0 and " << (int)get_stateless_obj()->get_port_count() - 1;
- generate_execute_err(result, ss.str());
- }
-
+ uint8_t port_id = parse_port(params, result);
TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
/* multiplier */
@@ -661,3 +593,54 @@ TrexRpcCmdUpdateTraffic::_run(const Json::Value &params, Json::Value &result) {
return (TREX_RPC_CMD_OK);
}
+/***************************
+ * validate
+ *
+ * checks that the port
+ * attached streams are
+ * valid as a program
+ **************************/
+trex_rpc_cmd_rc_e
+TrexRpcCmdValidate::_run(const Json::Value &params, Json::Value &result) {
+ uint8_t port_id = parse_port(params, result);
+ TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id);
+
+ const TrexStreamsGraphObj *graph = NULL;
+
+ try {
+ graph = port->validate();
+ }
+ catch (const TrexException &ex) {
+ generate_execute_err(result, ex.what());
+ }
+
+
+ result["result"]["rate"]["max_bps"] = graph->get_max_bps();
+ result["result"]["rate"]["max_pps"] = graph->get_max_pps();
+ result["result"]["rate"]["max_line_util"] = graph->get_max_bps() / port->get_port_speed_bps();
+
+ result["result"]["graph"]["events_count"] = (int)graph->get_events().size();
+
+ result["result"]["graph"]["events"] = Json::arrayValue;
+ Json::Value &events_json = result["result"]["graph"]["events"];
+
+ int index = 0;
+ for (const auto &ev : graph->get_events()) {
+ Json::Value ev_json;
+
+ ev_json["time_usec"] = ev.time;
+ ev_json["diff_bps"] = ev.diff_bps;
+ ev_json["diff_pps"] = ev.diff_pps;
+ ev_json["stream_id"] = ev.stream_id;
+
+ events_json.append(ev_json);
+
+ index++;
+ if (index >= 100) {
+ break;
+ }
+ }
+
+
+ return (TREX_RPC_CMD_OK);
+}
diff --git a/src/rpc-server/commands/trex_rpc_cmds.h b/src/rpc-server/commands/trex_rpc_cmds.h
index b4f37e3b..80bef3b0 100644
--- a/src/rpc-server/commands/trex_rpc_cmds.h
+++ b/src/rpc-server/commands/trex_rpc_cmds.h
@@ -114,5 +114,6 @@ TREX_RPC_CMD_DEFINE(TrexRpcCmdUpdateTraffic, "update_traffic", 2, true);
TREX_RPC_CMD_DEFINE(TrexRpcCmdSyncUser, "sync_user", 2, false);
+TREX_RPC_CMD_DEFINE(TrexRpcCmdValidate, "validate", 2, false);
#endif /* __TREX_RPC_CMD_H__ */
diff --git a/src/rpc-server/trex_rpc_cmds_table.cpp b/src/rpc-server/trex_rpc_cmds_table.cpp
index a65bbccf..52258b88 100644
--- a/src/rpc-server/trex_rpc_cmds_table.cpp
+++ b/src/rpc-server/trex_rpc_cmds_table.cpp
@@ -57,8 +57,11 @@ TrexRpcCommandsTable::TrexRpcCommandsTable() {
register_command(new TrexRpcCmdPauseTraffic());
register_command(new TrexRpcCmdResumeTraffic());
register_command(new TrexRpcCmdUpdateTraffic());
+
+ register_command(new TrexRpcCmdValidate());
}
+
TrexRpcCommandsTable::~TrexRpcCommandsTable() {
for (auto cmd : m_rpc_cmd_table) {
delete cmd.second;
diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp
index 95bdca0b..25fae038 100644
--- a/src/stateless/cp/trex_stateless_port.cpp
+++ b/src/stateless/cp/trex_stateless_port.cpp
@@ -126,9 +126,10 @@ TrexStatelessPort::start_traffic(const TrexPortMultiplier &mul, double duration)
TrexStreamsCompiler compiler;
TrexStreamsCompiledObj *compiled_obj = new TrexStreamsCompiledObj(m_port_id, per_core_mul);
- bool rc = compiler.compile(streams, *compiled_obj);
+ std::string fail_msg;
+ bool rc = compiler.compile(streams, *compiled_obj, &fail_msg);
if (!rc) {
- throw TrexRpcException("Failed to compile streams");
+ throw TrexRpcException(fail_msg);
}
/* generate a message to all the relevant DP cores to start transmitting */
@@ -393,7 +394,7 @@ TrexStatelessPort::on_dp_event_occured(TrexDpPortEvent::event_e event_type) {
}
uint64_t
-TrexStatelessPort::get_port_speed_bps() {
+TrexStatelessPort::get_port_speed_bps() const {
switch (m_speed) {
case TrexPlatformApi::SPEED_1G:
return (1LLU * 1000 * 1000 * 1000);
@@ -518,3 +519,31 @@ TrexPortMultiplier(const std::string &type_str, const std::string &op_str, doubl
}
+const TrexStreamsGraphObj *
+TrexStatelessPort::validate(void) {
+
+ /* first compile the graph */
+
+ vector<TrexStream *> streams;
+ get_object_list(streams);
+
+ if (streams.size() == 0) {
+ throw TrexException("no streams attached to port");
+ }
+
+ TrexStreamsCompiler compiler;
+ TrexStreamsCompiledObj compiled_obj(m_port_id, 1);
+
+ std::string fail_msg;
+ bool rc = compiler.compile(streams, compiled_obj, &fail_msg);
+ if (!rc) {
+ throw TrexException(fail_msg);
+ }
+
+ /* now create a stream graph */
+ if (!m_graph_obj) {
+ generate_streams_graph();
+ }
+
+ return m_graph_obj;
+}
diff --git a/src/stateless/cp/trex_stateless_port.h b/src/stateless/cp/trex_stateless_port.h
index 2d15a1cc..dbaac21d 100644
--- a/src/stateless/cp/trex_stateless_port.h
+++ b/src/stateless/cp/trex_stateless_port.h
@@ -76,6 +76,16 @@ public:
void release(void);
/**
+ * validate the state of the port before start
+ * it will return a stream graph
+ * containing information about the streams
+ * configured on this port
+ *
+ * on error it throws TrexException
+ */
+ const TrexStreamsGraphObj *validate(void);
+
+ /**
* start traffic
* throws TrexException in case of an error
*/
@@ -172,6 +182,7 @@ public:
verify_state(PORT_STATE_IDLE | PORT_STATE_STREAMS);
m_stream_table.add_stream(stream);
+ delete_streams_graph();
change_state(PORT_STATE_STREAMS);
}
@@ -180,6 +191,7 @@ public:
verify_state(PORT_STATE_STREAMS);
m_stream_table.remove_stream(stream);
+ delete_streams_graph();
if (m_stream_table.size() == 0) {
change_state(PORT_STATE_IDLE);
@@ -190,6 +202,7 @@ public:
verify_state(PORT_STATE_IDLE | PORT_STATE_STREAMS);
m_stream_table.remove_and_delete_all_streams();
+ delete_streams_graph();
change_state(PORT_STATE_IDLE);
}
@@ -219,6 +232,12 @@ public:
return (m_current_per_core_m * m_cores_id_list.size());
}
+ /**
+ * get port speed in bits per second
+ *
+ */
+ uint64_t get_port_speed_bps() const;
+
private:
@@ -269,11 +288,7 @@ private:
*/
double calculate_effective_mul(const TrexPortMultiplier &mul);
- /**
- * get port speed in bits per second
- *
- */
- uint64_t get_port_speed_bps();
+
/**
* generates a graph of streams graph
diff --git a/src/stateless/cp/trex_streams_compiler.cpp b/src/stateless/cp/trex_streams_compiler.cpp
index c8aa1e40..1c601f85 100644
--- a/src/stateless/cp/trex_streams_compiler.cpp
+++ b/src/stateless/cp/trex_streams_compiler.cpp
@@ -219,7 +219,7 @@ TrexStreamsCompiler::check_stream(const TrexStream *stream) {
/* cont. stream can point only on itself */
if (stream->get_type() == TrexStream::stCONTINUOUS) {
if (stream->m_next_stream_id != -1) {
- ss << "continous stream '" << stream->m_stream_id << "' cannot point on another stream";
+ ss << "continous stream '" << stream->m_stream_id << "' cannot point to another stream";
err(ss.str());
}
}
diff --git a/src/stateless/cp/trex_streams_compiler.h b/src/stateless/cp/trex_streams_compiler.h
index a4c12f8d..c1cf3811 100644
--- a/src/stateless/cp/trex_streams_compiler.h
+++ b/src/stateless/cp/trex_streams_compiler.h
@@ -157,6 +157,7 @@ public:
return m_rate_events;
}
+
private:
void add_rate_event(const rate_event_st &ev) {