From d71dbce9695f348b2e52e00c9efd53cb89c62aa5 Mon Sep 17 00:00:00 2001 From: imarom Date: Mon, 14 Dec 2015 11:03:53 -0500 Subject: bugs fixes 1. ignore your own force acquire of ports 2. TUI fixes --- .../trex_control_plane/client/trex_port.py | 4 ++- .../client/trex_stateless_client.py | 37 +++++++++++++++++----- .../trex_control_plane/console/trex_console.py | 28 +++++++++++++--- .../trex_control_plane/console/trex_tui.py | 2 ++ src/rpc-server/commands/trex_rpc_cmd_general.cpp | 3 +- src/rpc-server/commands/trex_rpc_cmds.h | 2 +- src/stateless/cp/trex_stateless_port.cpp | 6 +++- src/stateless/cp/trex_stateless_port.h | 2 +- 8 files changed, 66 insertions(+), 18 deletions(-) diff --git a/scripts/automation/trex_control_plane/client/trex_port.py b/scripts/automation/trex_control_plane/client/trex_port.py index 4f82e86a..0934313f 100644 --- a/scripts/automation/trex_control_plane/client/trex_port.py +++ b/scripts/automation/trex_control_plane/client/trex_port.py @@ -18,7 +18,7 @@ class Port(object): STATE_PAUSE: "PAUSE"} - def __init__ (self, port_id, speed, driver, user, comm_link): + def __init__ (self, port_id, speed, driver, user, comm_link, session_id): self.port_id = port_id self.state = self.STATE_IDLE self.handler = None @@ -30,6 +30,7 @@ class Port(object): self.speed = speed self.streams = {} self.profile = None + self.session_id = session_id self.port_stats = trex_stats.CPortStats(self) @@ -47,6 +48,7 @@ class Port(object): def acquire(self, force = False): params = {"port_id": self.port_id, "user": self.user, + "session_id": self.session_id, "force": force} command = RpcCmdData("acquire", params) 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 899805cf..0d52359d 100755 --- a/scripts/automation/trex_control_plane/client/trex_stateless_client.py +++ b/scripts/automation/trex_control_plane/client/trex_stateless_client.py @@ -46,11 +46,11 @@ class CTRexStatelessClient(object): """docstring for CTRexStatelessClient""" # verbose levels - VERBOSE_SILENCE = 0 + VERBOSE_QUIET = 0 VERBOSE_REGULAR = 1 VERBOSE_HIGH = 2 - def __init__(self, username, server="localhost", sync_port = 5050, async_port = 4500, virtual=False): + def __init__(self, username, server="localhost", sync_port = 5050, async_port = 4500, quiet = False, virtual = False): super(CTRexStatelessClient, self).__init__() self.user = username @@ -58,7 +58,10 @@ class CTRexStatelessClient(object): self.comm_link = CTRexStatelessClient.CCommLink(server, sync_port, virtual, self.prn_func) # default verbose level - self.verbose = self.VERBOSE_REGULAR + if not quiet: + self.verbose = self.VERBOSE_REGULAR + else: + self.verbose = self.VERBOSE_QUIET self.ports = {} self._connection_info = {"server": server, @@ -79,7 +82,7 @@ class CTRexStatelessClient(object): self.events = [] - + self.session_id = random.getrandbits(32) self.read_only = False self.connected = False @@ -90,9 +93,15 @@ class CTRexStatelessClient(object): return self.ports.get(port_id, None) - def get_server (self): + # connection server ip + def get_server_ip (self): return self.comm_link.get_server() + # connection server port + def get_server_port (self): + return self.comm_link.get_port() + + ################# events handler ###################### def add_event_log (self, msg, ev_type, show = False): @@ -107,7 +116,7 @@ class CTRexStatelessClient(object): if show: self.prn_func(format_text("\n{:^8} - {:}".format(prefix, format_text(msg, 'bold')))) - + def handle_async_stats_update(self, dump_data): global_stats = {} @@ -185,8 +194,16 @@ class CTRexStatelessClient(object): # port was stolen... elif (type == 5): + session_id = data['session_id'] + + # false alarm, its us + if session_id == self.session_id: + return + port_id = int(data['port_id']) - ev = "Port {0} was forcely taken".format(port_id) + who = data['who'] + + ev = "Port {0} was forcely taken by '{1}'".format(port_id, who) # call the handler self.async_event_port_forced_acquired(port_id) @@ -335,7 +352,7 @@ class CTRexStatelessClient(object): speed = self.system_info['ports'][port_id]['speed'] driver = self.system_info['ports'][port_id]['driver'] - self.ports[port_id] = Port(port_id, speed, driver, self.user, self.comm_link) + self.ports[port_id] = Port(port_id, speed, driver, self.user, self.comm_link, self.session_id) # sync the ports @@ -689,6 +706,7 @@ class CTRexStatelessClient(object): # reset def cmd_reset(self): + #self.release(self.get_acquired_ports()) rc = self.acquire(force = True) rc.annotate("Force acquiring all ports:") @@ -1176,6 +1194,9 @@ class CTRexStatelessClient(object): def get_server (self): return self.server + def get_port (self): + return self.port + def set_verbose(self, mode): self.verbose = mode return self.rpc_link.set_verbose(mode) diff --git a/scripts/automation/trex_control_plane/console/trex_console.py b/scripts/automation/trex_control_plane/console/trex_console.py index 325ba514..fe6dfe12 100755 --- a/scripts/automation/trex_control_plane/console/trex_console.py +++ b/scripts/automation/trex_control_plane/console/trex_console.py @@ -172,7 +172,7 @@ class TRexConsole(TRexGeneralCmd): def get_console_identifier(self): return "{context}_{server}".format(context=self.__class__.__name__, - server=self.stateless_client.get_server()) + server=self.stateless_client.get_server_ip()) def register_main_console_methods(self): main_names = set(self.trex_console.get_names()).difference(set(dir(self.__class__))) @@ -450,6 +450,7 @@ class TRexConsole(TRexGeneralCmd): self.stateless_client.clear_events() print format_text("\n\nEvent log was cleared\n\n") + # tui @verify_connected def do_tui (self, line): @@ -465,15 +466,26 @@ class TRexConsole(TRexGeneralCmd): return if opts.xterm: - subprocess.Popen(['xterm', '-geometry', '105x40', '-e', './trex-console', '-t']) + exe = '' + if os.path.isfile('/usr/bin/wmctrl'): + exe += '/usr/bin/wmctrl -r trex_tui -b add,above;' + + exe += './trex-console -t -q -s {0} -p {1}'.format(self.stateless_client.get_server_ip(), self.stateless_client.get_server_port()) + + cmd = ['xterm', '-geometry', '105x40', '-title', 'trex_tui', '-e', exe] + subprocess.Popen(cmd) + return save_verbose = self.stateless_client.get_verbose() - self.stateless_client.set_verbose(self.stateless_client.VERBOSE_SILENCE) + self.stateless_client.set_verbose(self.stateless_client.VERBOSE_QUIET) self.tui.show() self.stateless_client.set_verbose(save_verbose) + def help_tui (self): + do_tui("-h") + # quit function def do_quit(self, line): '''Exit the client\n''' @@ -568,6 +580,11 @@ def setParserOptions(): action="store_true", help="Starts with TUI mode", default = False) + + parser.add_argument("-q", "--quiet", dest="quiet", + action="store_true", help="Starts with all outputs suppressed", + default = False) + return parser @@ -576,9 +593,10 @@ def main(): options = parser.parse_args() # Stateless client connection - stateless_client = CTRexStatelessClient(options.user, options.server, options.port, options.pub) + stateless_client = CTRexStatelessClient(options.user, options.server, options.port, options.pub, options.quiet) - print "\nlogged as {0}".format(format_text(options.user, 'bold')) + if not options.quiet: + print "\nlogged as {0}".format(format_text(options.user, 'bold')) # TUI or no acquire will give us READ ONLY mode if options.tui or not options.acquire: diff --git a/scripts/automation/trex_control_plane/console/trex_tui.py b/scripts/automation/trex_control_plane/console/trex_tui.py index 3a89097f..c8cdaa16 100644 --- a/scripts/automation/trex_control_plane/console/trex_tui.py +++ b/scripts/automation/trex_control_plane/console/trex_tui.py @@ -393,6 +393,7 @@ class TrexTUI(): def clear_screen (self): os.system('clear') + #sys.stderr.write("\x1b[2J\x1b[H") @@ -465,3 +466,4 @@ class TrexTUI(): def get_state (self): return self.state + diff --git a/src/rpc-server/commands/trex_rpc_cmd_general.cpp b/src/rpc-server/commands/trex_rpc_cmd_general.cpp index a2d4c284..a701f6db 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_general.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_general.cpp @@ -236,12 +236,13 @@ TrexRpcCmdAcquire::_run(const Json::Value ¶ms, Json::Value &result) { const string &new_owner = parse_string(params, "user", result); bool force = parse_bool(params, "force", result); + uint32_t session_id = parse_uint32(params, "session_id", result); /* if not free and not you and not force - fail */ TrexStatelessPort *port = get_stateless_obj()->get_port_by_id(port_id); try { - port->acquire(new_owner, force); + port->acquire(new_owner, session_id, force); } catch (const TrexRpcException &ex) { generate_execute_err(result, ex.what()); } diff --git a/src/rpc-server/commands/trex_rpc_cmds.h b/src/rpc-server/commands/trex_rpc_cmds.h index c22ef390..b9be1fbe 100644 --- a/src/rpc-server/commands/trex_rpc_cmds.h +++ b/src/rpc-server/commands/trex_rpc_cmds.h @@ -70,7 +70,7 @@ void get_hostname(std::string &hostname); * ownership */ TREX_RPC_CMD_DEFINE(TrexRpcCmdGetOwner, "get_owner", 1, false); -TREX_RPC_CMD_DEFINE(TrexRpcCmdAcquire, "acquire", 3, false); +TREX_RPC_CMD_DEFINE(TrexRpcCmdAcquire, "acquire", 4, false); TREX_RPC_CMD_DEFINE(TrexRpcCmdRelease, "release", 1, true); diff --git a/src/stateless/cp/trex_stateless_port.cpp b/src/stateless/cp/trex_stateless_port.cpp index 9770c735..3a64f8c5 100644 --- a/src/stateless/cp/trex_stateless_port.cpp +++ b/src/stateless/cp/trex_stateless_port.cpp @@ -84,7 +84,7 @@ TrexStatelessPort::TrexStatelessPort(uint8_t port_id, const TrexPlatformApi *api * @param force */ void -TrexStatelessPort::acquire(const std::string &user, bool force) { +TrexStatelessPort::acquire(const std::string &user, uint32_t session_id, bool force) { /* if port is free - just take it */ if (get_owner().is_free()) { @@ -97,7 +97,11 @@ TrexStatelessPort::acquire(const std::string &user, bool force) { /* inform the other client of the steal... */ Json::Value data; + data["port_id"] = m_port_id; + data["who"] = user; + data["session_id"] = session_id; + get_stateless_obj()->get_publisher()->publish_event(TrexPublisher::EVENT_PORT_FORCE_ACQUIRED, data); } else { diff --git a/src/stateless/cp/trex_stateless_port.h b/src/stateless/cp/trex_stateless_port.h index 4988b46a..a529d38f 100644 --- a/src/stateless/cp/trex_stateless_port.h +++ b/src/stateless/cp/trex_stateless_port.h @@ -138,7 +138,7 @@ public: * acquire port * throws TrexException in case of an error */ - void acquire(const std::string &user, bool force = false); + void acquire(const std::string &user, uint32_t session_id, bool force = false); /** * release the port from the current user -- cgit From bfb15053ea5d21bc0502f3102cd83407fafddf75 Mon Sep 17 00:00:00 2001 From: imarom Date: Tue, 15 Dec 2015 04:26:21 -0500 Subject: moved all return code values to RC types (better for batch rc) also few fixes --- .../trex_control_plane/client/trex_async_client.py | 5 +- .../trex_control_plane/client/trex_port.py | 97 +++++++++++++--------- .../client/trex_stateless_client.py | 62 +++++--------- .../client_utils/jsonrpc_client.py | 48 +++++------ .../trex_control_plane/common/trex_types.py | 6 +- .../trex_control_plane/console/trex_tui.py | 5 +- src/rpc-server/commands/trex_rpc_cmd_stream.cpp | 2 +- src/rpc-server/trex_rpc_cmd.cpp | 12 +++ 8 files changed, 123 insertions(+), 114 deletions(-) diff --git a/scripts/automation/trex_control_plane/client/trex_async_client.py b/scripts/automation/trex_control_plane/client/trex_async_client.py index 00304886..459d6915 100644 --- a/scripts/automation/trex_control_plane/client/trex_async_client.py +++ b/scripts/automation/trex_control_plane/client/trex_async_client.py @@ -19,6 +19,7 @@ import re from common.trex_stats import * from common.trex_streams import * +from common.trex_types import * # basic async stats class class CTRexAsyncStats(object): @@ -204,9 +205,9 @@ class CTRexAsyncClient(): time.sleep(0.01) if time.time() > timeout: self.disconnect() - return False, "*** [subscriber] - no data flow from server at : " + self.tr + return RC_ERR("*** [subscriber] - no data flow from server at : " + self.tr) - return True, "" + return RC_OK() # disconnect diff --git a/scripts/automation/trex_control_plane/client/trex_port.py b/scripts/automation/trex_control_plane/client/trex_port.py index 0934313f..54b4945e 100644 --- a/scripts/automation/trex_control_plane/client/trex_port.py +++ b/scripts/automation/trex_control_plane/client/trex_port.py @@ -3,6 +3,22 @@ from collections import namedtuple from common.trex_types import * from common import trex_stats + +########## utlity ############ +def mult_to_factor (mult, max_bps, max_pps, line_util): + if mult['type'] == 'raw': + return mult['value'] + + if mult['type'] == 'bps': + return mult['value'] / max_bps + + if mult['type'] == 'pps': + return mult['value'] / max_pps + + if mult['type'] == 'percentage': + return mult['value'] / line_util + + # describes a single port class Port(object): STATE_DOWN = 0 @@ -53,11 +69,11 @@ class Port(object): command = RpcCmdData("acquire", params) rc = self.transmit(command.method, command.params) - if rc.success: - self.handler = rc.data + if rc.good(): + self.handler = rc.data() return self.ok() else: - return self.err(rc.data) + return self.err(rc.err()) # release the port def release(self): @@ -68,10 +84,10 @@ class Port(object): rc = self.transmit(command.method, command.params) self.handler = None - if rc.success: + if rc.good(): return self.ok() else: - return self.err(rc.data) + return self.err(rc.err()) def is_acquired(self): return (self.handler != None) @@ -91,11 +107,11 @@ class Port(object): command = RpcCmdData("get_port_status", params) rc = self.transmit(command.method, command.params) - if not rc.success: - return self.err(rc.data) + if rc.bad(): + return self.err(rc.err()) # sync the port - port_state = rc.data['state'] + port_state = rc.data()['state'] if port_state == "DOWN": self.state = self.STATE_DOWN @@ -130,10 +146,9 @@ class Port(object): "stream_id": stream_id, "stream": stream_obj} - rc, data = self.transmit("add_stream", params) - if not rc: - r = self.err(data) - print r.good() + rc = self.transmit("add_stream", params) + if rc.bad(): + return self.err(rc.err()) # add the stream self.streams[stream_id] = stream_obj @@ -156,10 +171,11 @@ class Port(object): cmd = RpcCmdData('add_stream', params) batch.append(cmd) - rc, data = self.transmit_batch(batch) + rc = self.transmit_batch(batch) + if rc.bad(): + return self.err(rc.err()) - if not rc: - return self.err(data) + # validate that every action succeeded # add the stream for stream in streams_list: @@ -181,9 +197,9 @@ class Port(object): "stream_id": stream_id} - rc, data = self.transmit("remove_stream", params) - if not rc: - return self.err(data) + rc = self.transmit("remove_stream", params) + if rc.bad(): + return self.err(rc.err()) self.streams[stream_id] = None @@ -197,9 +213,9 @@ class Port(object): params = {"handler": self.handler, "port_id": self.port_id} - rc, data = self.transmit("remove_all_streams", params) - if not rc: - return self.err(data) + rc = self.transmit("remove_all_streams", params) + if rc.bad(): + return self.err(rc.err()) self.streams = {} @@ -233,9 +249,9 @@ class Port(object): "mul": mul, "duration": duration} - rc, data = self.transmit("start_traffic", params) - if not rc: - return self.err(data) + rc = self.transmit("start_traffic", params) + if rc.bad(): + return self.err(rc.err()) self.state = self.STATE_TX @@ -251,9 +267,9 @@ class Port(object): params = {"handler": self.handler, "port_id": self.port_id} - rc, data = self.transmit("stop_traffic", params) - if not rc: - return self.err(data) + rc = self.transmit("stop_traffic", params) + if rc.bad(): + return self.err(rc.err()) # only valid state after stop self.state = self.STATE_STREAMS @@ -268,9 +284,9 @@ class Port(object): params = {"handler": self.handler, "port_id": self.port_id} - rc, data = self.transmit("pause_traffic", params) - if not rc: - return self.err(data) + rc = self.transmit("pause_traffic", params) + if rc.bad(): + return self.err(rc.err()) # only valid state after stop self.state = self.STATE_PAUSE @@ -286,9 +302,9 @@ class Port(object): params = {"handler": self.handler, "port_id": self.port_id} - rc, data = self.transmit("resume_traffic", params) - if not rc: - return self.err(data) + rc = self.transmit("resume_traffic", params) + if rc.bad(): + return self.err(rc.err()) # only valid state after stop self.state = self.STATE_TX @@ -304,9 +320,9 @@ class Port(object): "port_id": self.port_id, "mul": mul} - rc, data = self.transmit("update_traffic", params) - if not rc: - return self.err(data) + rc = self.transmit("update_traffic", params) + if rc.bad(): + return self.err(rc.err()) return self.ok() @@ -322,11 +338,11 @@ class Port(object): params = {"handler": self.handler, "port_id": self.port_id} - rc, data = self.transmit("validate", params) - if not rc: - return self.err(data) + rc = self.transmit("validate", params) + if rc.bad(): + return self.err(rc.err()) - self.profile = data + self.profile = rc.data() return self.ok() @@ -411,3 +427,4 @@ class Port(object): def async_event_forced_acquired (self): self.handler = None + 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 0d52359d..75c1c06f 100755 --- a/scripts/automation/trex_control_plane/client/trex_stateless_client.py +++ b/scripts/automation/trex_control_plane/client/trex_stateless_client.py @@ -26,22 +26,6 @@ from common.trex_types import * from trex_async_client import CTRexAsyncClient -########## utlity ############ -def mult_to_factor (mult, max_bps, max_pps, line_util): - if mult['type'] == 'raw': - return mult['value'] - - if mult['type'] == 'bps': - return mult['value'] / max_bps - - if mult['type'] == 'pps': - return mult['value'] / max_pps - - if mult['type'] == 'percentage': - return mult['value'] / line_util - - - class CTRexStatelessClient(object): """docstring for CTRexStatelessClient""" @@ -317,35 +301,36 @@ class CTRexStatelessClient(object): self.connected = False # connect sync channel - rc, data = self.comm_link.connect() - if not rc: - return RC_ERR(data) + rc = self.comm_link.connect() + if rc.bad(): + return rc # connect async channel - rc, data = self.async_client.connect() - if not rc: - return RC_ERR(data) + rc = self.async_client.connect() + if rc.bad(): + return rc # version - rc, data = self.transmit("get_version") - if not rc: - return RC_ERR(data) + rc = self.transmit("get_version") + if rc.bad(): + return rc - self.server_version = data - self.global_stats.server_version = data + self.server_version = rc.data() + self.global_stats.server_version = rc.data() # cache system info - rc, data = self.transmit("get_system_info") - if not rc: - return RC_ERR(data) - self.system_info = data + rc = self.transmit("get_system_info") + if rc.bad(): + return rc + + self.system_info = rc.data() # cache supported commands - rc, data = self.transmit("get_supported_cmds") - if not rc: - return RC_ERR(data) + rc = self.transmit("get_supported_cmds") + if rc.bad(): + return rc - self.supported_cmds = data + self.supported_cmds = rc.data() # create ports for port_id in xrange(self.get_port_count()): @@ -498,14 +483,12 @@ class CTRexStatelessClient(object): # ping server def ping(self): - rc, info = self.transmit("ping") - return RC(rc, info) + return self.transmit("ping") def get_global_stats(self): - rc, info = self.transmit("get_global_stats") - return RC(rc, info) + return self.transmit("get_global_stats") ########## port commands ############## @@ -705,7 +688,6 @@ class CTRexStatelessClient(object): # reset def cmd_reset(self): - #self.release(self.get_acquired_ports()) rc = self.acquire(force = True) 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 ce98fbc6..bdae7bd9 100755 --- a/scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py +++ b/scripts/automation/trex_control_plane/client_utils/jsonrpc_client.py @@ -7,8 +7,7 @@ import general_utils import re from time import sleep from collections import namedtuple - -CmdResponse = namedtuple('CmdResponse', ['success', 'data']) +from common.trex_types import * class bcolors: BLUE = '\033[94m' @@ -33,15 +32,11 @@ class BatchMessage(object): def invoke(self, block = False): if not self.rpc_client.connected: - return False, "Not connected to server" + return RC_ERR("Not connected to server") msg = json.dumps(self.batch_list) - rc, resp_list = self.rpc_client.send_raw_msg(msg) - if len(self.batch_list) == 1: - return CmdResponse(True, [CmdResponse(rc, resp_list)]) - else: - return CmdResponse(rc, resp_list) + return self.rpc_client.send_raw_msg(msg) # JSON RPC v2.0 client @@ -114,7 +109,7 @@ class JsonRpcClient(object): def invoke_rpc_method (self, method_name, params = {}): if not self.connected: - return CmdResponse(False, "Not connected to server") + return RC_ERR("Not connected to server") id, msg = self.create_jsonrpc_v2(method_name, params) @@ -135,7 +130,7 @@ class JsonRpcClient(object): tries += 1 if tries > 10: self.disconnect() - return CmdResponse(False, "*** [RPC] - Failed to send message to server") + return RC_ERR("*** [RPC] - Failed to send message to server") tries = 0 @@ -147,7 +142,7 @@ class JsonRpcClient(object): tries += 1 if tries > 10: self.disconnect() - return CmdResponse(False, "*** [RPC] - Failed to get server response") + return RC_ERR("*** [RPC] - Failed to get server response") self.verbose_msg("Server Response:\n\n" + self.pretty_json(response) + "\n") @@ -158,36 +153,35 @@ class JsonRpcClient(object): response_json = json.loads(response) if isinstance(response_json, list): - rc_list = [] + rc_batch = RC() for single_response in response_json: - rc, msg = self.process_single_response(single_response) - rc_list.append( CmdResponse(rc, msg) ) + rc = self.process_single_response(single_response) + rc_batch.add(rc) - return CmdResponse(True, rc_list) + return rc_batch else: - rc, msg = self.process_single_response(response_json) - return CmdResponse(rc, msg) + return self.process_single_response(response_json) def process_single_response (self, response_json): if (response_json.get("jsonrpc") != "2.0"): - return False, "Malformed Response ({0})".format(str(response_json)) + return RC_ERR("Malformed Response ({0})".format(str(response_json))) # error reported by server if ("error" in response_json): if "specific_err" in response_json["error"]: - return False, response_json["error"]["specific_err"] + return RC_ERR(response_json["error"]["specific_err"]) else: - return False, response_json["error"]["message"] + return RC_ERR(response_json["error"]["message"]) # if no error there should be a result if ("result" not in response_json): - return False, "Malformed Response ({0})".format(str(response_json)) + return RC_ERR("Malformed Response ({0})".format(str(response_json))) - return True, response_json["result"] + return RC_OK(response_json["result"]) @@ -199,9 +193,9 @@ class JsonRpcClient(object): self.socket.close(linger = 0) self.context.destroy(linger = 0) self.connected = False - return True, "" + return RC_OK() else: - return False, "Not connected to server" + return RC_ERR("Not connected to server") def connect(self, server = None, port = None, prn_func = None): @@ -226,14 +220,14 @@ class JsonRpcClient(object): try: self.socket.connect(self.transport) except zmq.error.ZMQError as e: - return False, "ZMQ Error: Bad server or port name: " + str(e) + return RC_ERR("ZMQ Error: Bad server or port name: " + str(e)) self.socket.setsockopt(zmq.SNDTIMEO, 1000) self.socket.setsockopt(zmq.RCVTIMEO, 1000) self.connected = True - return True, "" + return RC_OK() def reconnect(self): @@ -241,7 +235,7 @@ class JsonRpcClient(object): return self.connect() if not self.connected: - return False, "Not connected to server" + return RC_ERR("Not connected to server") # reconnect return self.connect(self.server, self.port) diff --git a/scripts/automation/trex_control_plane/common/trex_types.py b/scripts/automation/trex_control_plane/common/trex_types.py index 3de36e4c..7c3f04c5 100644 --- a/scripts/automation/trex_control_plane/common/trex_types.py +++ b/scripts/automation/trex_control_plane/common/trex_types.py @@ -31,10 +31,12 @@ class RC(): return not self.good() def data (self): - return [x.data if x.rc else "" for x in self.rc_list] + d = [x.data if x.rc else "" for x in self.rc_list] + return (d if len(d) > 1 else d[0]) def err (self): - return [x.data if not x.rc else "" for x in self.rc_list] + e = [x.data if not x.rc else "" for x in self.rc_list] + return (e if len(e) > 1 else e[0]) def annotate (self, desc = None, show_status = True): if desc: diff --git a/scripts/automation/trex_control_plane/console/trex_tui.py b/scripts/automation/trex_control_plane/console/trex_tui.py index c8cdaa16..6b0aa50a 100644 --- a/scripts/automation/trex_control_plane/console/trex_tui.py +++ b/scripts/automation/trex_control_plane/console/trex_tui.py @@ -392,8 +392,9 @@ class TrexTUI(): def clear_screen (self): - os.system('clear') - #sys.stderr.write("\x1b[2J\x1b[H") + #os.system('clear') + # maybe this is faster ? + sys.stderr.write("\x1b[2J\x1b[H") diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp index fa3d96b2..305ccc17 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp @@ -265,7 +265,7 @@ void TrexRpcCmdAddStream::parse_vm(const Json::Value &vm, TrexStream *stream, Json::Value &result) { /* array of VM instructions on vm */ for (int i = 0; i < vm.size(); i++) { - const Json::Value & inst = vm[i]; + const Json::Value & inst = parse_object(vm, i, result); auto vm_types = {"fix_checksum_ipv4", "flow_var", "write_flow_var"}; std::string vm_type = parse_choice(inst, "type", vm_types, result); diff --git a/src/rpc-server/trex_rpc_cmd.cpp b/src/rpc-server/trex_rpc_cmd.cpp index d4eef1f7..8f0ffbad 100644 --- a/src/rpc-server/trex_rpc_cmd.cpp +++ b/src/rpc-server/trex_rpc_cmd.cpp @@ -203,12 +203,24 @@ TrexRpcCommand::parse_string(const Json::Value &parent, const std::string &name, return parent[name].asString(); } +/** + * object version + */ const Json::Value & TrexRpcCommand::parse_object(const Json::Value &parent, const std::string &name, Json::Value &result) { check_field_type(parent, name, FIELD_TYPE_OBJ, result); return parent[name]; } +/** + * index version + */ +const Json::Value & +TrexRpcCommand::parse_object(const Json::Value &parent, int index, Json::Value &result) { + check_field_type(parent, index, FIELD_TYPE_OBJ, result); + return parent[index]; +} + const Json::Value & TrexRpcCommand::parse_array(const Json::Value &parent, const std::string &name, Json::Value &result) { check_field_type(parent, name, FIELD_TYPE_ARRAY, result); -- cgit From d449e87f1b5bdf4d57e6ef22772be94887a1e94d Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Tue, 15 Dec 2015 04:30:51 +0200 Subject: fixing crash in ipv6 rx-check mode --- src/bp_sim.cpp | 2 ++ 1 file changed, 2 insertions(+) diff --git a/src/bp_sim.cpp b/src/bp_sim.cpp index 1383518b..49cdbd23 100755 --- a/src/bp_sim.cpp +++ b/src/bp_sim.cpp @@ -5980,6 +5980,7 @@ bool CSimplePacketParser::Parse(){ case EthernetHeader::Protocol::IPv6 : // IPv6 packet ipv6=(IPv6Header *)(p+14); + m_l4 = (uint8_t *)ipv6 + ipv6->getHeaderLength(); protocol = ipv6->getNextHdr(); m_option_offset = 14 +IPV6_HDR_LEN; break; @@ -5996,6 +5997,7 @@ bool CSimplePacketParser::Parse(){ case EthernetHeader::Protocol::IPv6 : // IPv6 packet ipv6=(IPv6Header *)(p+18); + m_l4 = (uint8_t *)ipv6 + ipv6->getHeaderLength(); protocol = ipv6->getNextHdr(); m_option_offset = 18 + IPV6_HDR_LEN; break; -- cgit From 7b1796d823b38f7c8c801e19c51a4044bc39b17c Mon Sep 17 00:00:00 2001 From: Yaroslav Brustinov Date: Tue, 15 Dec 2015 17:46:09 +0200 Subject: TRex API: increase timeout (from 30 to 40) of waiting for TRex to change state from Starting to Idle or Running. --- scripts/automation/trex_control_plane/client/trex_client.py | 4 ++-- scripts/automation/trex_control_plane/server/trex_server.py | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/scripts/automation/trex_control_plane/client/trex_client.py b/scripts/automation/trex_control_plane/client/trex_client.py index 49807014..a8669011 100755 --- a/scripts/automation/trex_control_plane/client/trex_client.py +++ b/scripts/automation/trex_control_plane/client/trex_client.py @@ -88,7 +88,7 @@ class CTRexClient(object): finally: self.prompt_verbose_data() - def start_trex (self, f, d, block_to_success = True, timeout = 30, user = None, trex_development = False, **trex_cmd_options): + def start_trex (self, f, d, block_to_success = True, timeout = 40, user = None, trex_development = False, **trex_cmd_options): """ Request to start a TRex run on server. @@ -104,7 +104,7 @@ class CTRexClient(object): timeout : int maximum time (in seconds) to wait in blocking state until TRex changes state from 'Starting' to either 'Idle' or 'Running' - default value: **30** + default value: **40** user : str the identity of the the run issuer. trex_cmd_options : key, val diff --git a/scripts/automation/trex_control_plane/server/trex_server.py b/scripts/automation/trex_control_plane/server/trex_server.py index 9868d6c8..bf788d35 100755 --- a/scripts/automation/trex_control_plane/server/trex_server.py +++ b/scripts/automation/trex_control_plane/server/trex_server.py @@ -259,7 +259,7 @@ class CTRexServer(object): return False - def start_trex(self, trex_cmd_options, user, block_to_success = True, timeout = 30): + def start_trex(self, trex_cmd_options, user, block_to_success = True, timeout = 40): with self.start_lock: logger.info("Processing start_trex() command.") if self.is_reserved(): -- cgit