summaryrefslogtreecommitdiffstats
path: root/scripts/automation/trex_control_plane/stl
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2017-01-22 16:20:45 +0200
committerimarom <imarom@cisco.com>2017-01-22 16:20:45 +0200
commit904eacd9be1230efb7ae0ab7997ec131b588ec8a (patch)
tree8e4bcd1b1a5f683efdb8f3eeb962acefc3201961 /scripts/automation/trex_control_plane/stl
parentd2f1c8451e2e8ffc47b208f68f9b16697d706d60 (diff)
parentb81cdb6c2d6d118c1c346e7c8dae6a5e747d867d (diff)
Merge branch 'master' into capture
Signed-off-by: imarom <imarom@cisco.com> Conflicts: scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_jsonrpc_client.py scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py src/main_dpdk.cpp
Diffstat (limited to 'scripts/automation/trex_control_plane/stl')
-rwxr-xr-xscripts/automation/trex_control_plane/stl/console/trex_console.py21
-rwxr-xr-xscripts/automation/trex_control_plane/stl/services/scapy_server/scapy_service.py93
-rwxr-xr-xscripts/automation/trex_control_plane/stl/services/scapy_server/scapy_zmq_server.py5
-rw-r--r--scripts/automation/trex_control_plane/stl/services/scapy_server/templates/ICMP echo request.trp1
-rw-r--r--scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv4/ICMP.trp1
-rw-r--r--scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv4/TCP.trp1
-rw-r--r--scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv4/UDP.trp1
-rw-r--r--scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv6/ICMP.trp1
-rw-r--r--scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv6/TCP.trp1
-rw-r--r--scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv6/UDP.trp1
-rw-r--r--scripts/automation/trex_control_plane/stl/services/scapy_server/templates/TCP-SYN.trp1
-rw-r--r--scripts/automation/trex_control_plane/stl/services/scapy_server/unit_tests/basetest.py9
-rw-r--r--scripts/automation/trex_control_plane/stl/services/scapy_server/unit_tests/test_scapy_service.py40
-rwxr-xr-xscripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py45
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_jsonrpc_client.py28
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py10
16 files changed, 213 insertions, 46 deletions
diff --git a/scripts/automation/trex_control_plane/stl/console/trex_console.py b/scripts/automation/trex_control_plane/stl/console/trex_console.py
index 270ef31c..83f36820 100755
--- a/scripts/automation/trex_control_plane/stl/console/trex_console.py
+++ b/scripts/automation/trex_control_plane/stl/console/trex_console.py
@@ -859,10 +859,10 @@ def show_intro (logger, c):
# find out which NICs the server has
port_types = {}
for port in x['ports']:
- if 'supp_speeds' in port:
+ if 'supp_speeds' in port and port['supp_speeds']:
speed = max(port['supp_speeds']) // 1000
else:
- speed = port['speed']
+ speed = c.ports[port['index']].get_speed_gbps()
key = (speed, port.get('description', port['driver']))
if key not in port_types:
port_types[key] = 0
@@ -927,17 +927,16 @@ def main():
if options.readonly:
logger.log(format_text("\nRead only mode - only few commands will be available", 'bold'))
- show_intro(logger, stateless_client)
-
-
- # a script mode
- if options.batch:
- cont = run_script_file(options.batch[0], stateless_client)
- if not cont:
- return
-
# console
try:
+ show_intro(logger, stateless_client)
+
+ # a script mode
+ if options.batch:
+ cont = run_script_file(options.batch[0], stateless_client)
+ if not cont:
+ return
+
console = TRexConsole(stateless_client, options.verbose)
logger.prompt_redraw = console.prompt_redraw
diff --git a/scripts/automation/trex_control_plane/stl/services/scapy_server/scapy_service.py b/scripts/automation/trex_control_plane/stl/services/scapy_server/scapy_service.py
index 654b98f7..7b19896b 100755
--- a/scripts/automation/trex_control_plane/stl/services/scapy_server/scapy_service.py
+++ b/scripts/automation/trex_control_plane/stl/services/scapy_server/scapy_service.py
@@ -264,6 +264,34 @@ class Scapy_service_api():
"""
pass
+ def get_templates(self,client_v_handler):
+ """ get_templates(self,client_v_handler)
+
+ Returns an array of templates, which normally can be used for creating packet
+
+ Parameters
+ ----------
+
+ Returns
+ -------
+ array of templates
+ """
+ pass
+
+ def get_template(self,client_v_handler,template):
+ """ get_template(self,client_v_handler,template)
+
+ Returns a template, which normally can be used for creating packet
+
+ Parameters
+ ----------
+
+ Returns
+ -------
+ base64 of template content
+ """
+ pass
+
def is_python(version):
return version == sys.version_info[0]
@@ -853,7 +881,7 @@ class Scapy_service(Scapy_service_api):
for instruction_def in instructions_def:
instruction_id = instruction_def['id']
instruction_class = self._vm_instructions[instruction_id]
- parameters = {k: self._sanitize_value(k, v) for (k, v) in instruction_def['parameters'].iteritems()}
+ parameters = {k: self._sanitize_value(k, v) for (k, v) in instruction_def['parameters'].items()}
instructions.append(instruction_class(**parameters))
fe_parameters = field_engine_model_descriptor['global_parameters']
@@ -933,7 +961,7 @@ class Scapy_service(Scapy_service_api):
else:
return pkt_class()
-
+
def _get_payload_classes(self, pkt_class):
# tries to find, which subclasses allowed.
# this can take long time, since it tries to build packets with all subclasses(O(N))
@@ -950,6 +978,61 @@ class Scapy_service(Scapy_service_api):
pass
return allowed_subclasses
+
+
+ def _get_templates(self):
+ # Make sure you understand the three return values of os.walk:
+ #
+ # for root, subdirs, files in os.walk(rootdir):
+ # has the following meaning:
+ #
+ # root: Current path which is "walked through"
+ # subdirs: Files in root of type directory
+ # files: Files in root (not in subdirs) of type other than directory
+ # And please use os.path.join instead of concatenating with a slash!
+ # Your problem is filePath = rootdir + '/' + file - you must concatenate the currently "walked" folder instead of the topmost folder.
+ # So that must be filePath = os.path.join(root, file). BTW "file" is a builtin, so you don't normally use it as variable name.
+
+ templates = []
+ for root, subdirs, files in os.walk("templates"):
+ for file in files:
+ if file.endswith('.trp'):
+ try:
+ f = os.path.join(root, file)
+ o = open(f)
+ c = json.loads(o.read())
+ o.close()
+ id = f.replace("templates" + os.path.sep, "", 1)
+ id = id.split(os.path.sep)
+ id[-1] = id[-1].replace(".trp", "", 1)
+ id = "/".join(id)
+ t = {
+ "id": id,
+ "meta": {
+ "name": c["metadata"]["caption"],
+ "description": ""
+ }
+ }
+ templates.append(t)
+ except:
+ pass
+ return templates
+
+ def _get_template(self,template):
+ id = template["id"]
+ f2 = "templates" + os.path.sep + os.path.sep.join(id.split("/")) + ".trp"
+ for c in r'[]\;,><&*:%=+@!#^()|?^':
+ id = id.replace(c,'')
+ id = id.replace("..", "")
+ id = id.split("/")
+ f = "templates" + os.path.sep + os.path.sep.join(id) + ".trp"
+ if f != f2:
+ return ""
+ with open(f, 'r') as content_file:
+ content = base64.b64encode(content_file.read())
+ return content
+
+
def _get_fields_definition(self, pkt_class, fieldsDef):
# fieldsDef - array of field definitions(or empty array)
fields = []
@@ -1010,6 +1093,12 @@ class Scapy_service(Scapy_service_api):
return protocolDef['payload']
return [c.__name__ for c in self._get_payload_classes(pkt_class)]
+ def get_templates(self,client_v_handler):
+ return self._get_templates()
+
+ def get_template(self,client_v_handler,template):
+ return self._get_template(template)
+
#input in string encoded base64
def check_update_of_dbs(self,client_v_handler,db_md5,field_md5):
if not (self._verify_version_handler(client_v_handler)):
diff --git a/scripts/automation/trex_control_plane/stl/services/scapy_server/scapy_zmq_server.py b/scripts/automation/trex_control_plane/stl/services/scapy_server/scapy_zmq_server.py
index 6489b36a..0788229a 100755
--- a/scripts/automation/trex_control_plane/stl/services/scapy_server/scapy_zmq_server.py
+++ b/scripts/automation/trex_control_plane/stl/services/scapy_server/scapy_zmq_server.py
@@ -103,7 +103,10 @@ class Scapy_server():
self.context = zmq.Context()
self.socket = self.context.socket(zmq.REP)
self.socket.bind("tcp://*:"+str(port))
- self.IP_address = socket.gethostbyname(socket.gethostname())
+ try:
+ self.IP_address = socket.gethostbyname(socket.gethostname())
+ except:
+ self.IP_address = '0.0.0.0'
self.logger = logging.getLogger('scapy_logger')
self.logger.setLevel(logging.INFO)
console_h = logging.StreamHandler(sys.__stdout__)
diff --git a/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/ICMP echo request.trp b/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/ICMP echo request.trp
new file mode 100644
index 00000000..f8988a5f
--- /dev/null
+++ b/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/ICMP echo request.trp
@@ -0,0 +1 @@
+{"fileType":"trex-packet-editor","version":"1.0.0","metadata":{"caption":"ICMP echo request"},"packet":[{"id":"Ether","fields":[]},{"id":"IP","fields":[]},{"id":"ICMP","fields":[{"id":"type","value":"8"}]}],"fePrarameters":{"cache_size":"1000"},"feInstructions":[]} \ No newline at end of file
diff --git a/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv4/ICMP.trp b/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv4/ICMP.trp
new file mode 100644
index 00000000..4ab1a1ae
--- /dev/null
+++ b/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv4/ICMP.trp
@@ -0,0 +1 @@
+{"fileType":"trex-packet-editor","version":"1.0.0","metadata":{"caption":"ICMP echo request"},"packet":[{"id":"Ether","fields":[{"id":"type","value":"2048"}]},{"id":"IP","fields":[]},{"id":"ICMP","fields":[]}],"fePrarameters":{"cache_size":"1000"},"feInstructions":[]} \ No newline at end of file
diff --git a/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv4/TCP.trp b/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv4/TCP.trp
new file mode 100644
index 00000000..6c94592c
--- /dev/null
+++ b/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv4/TCP.trp
@@ -0,0 +1 @@
+{"fileType":"trex-packet-editor","version":"1.0.0","metadata":{"caption":"ICMP echo request"},"packet":[{"id":"Ether","fields":[{"id":"type","value":"2048"}]},{"id":"IP","fields":[]},{"id":"TCP","fields":[]}],"fePrarameters":{"cache_size":"1000"},"feInstructions":[]} \ No newline at end of file
diff --git a/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv4/UDP.trp b/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv4/UDP.trp
new file mode 100644
index 00000000..bef92993
--- /dev/null
+++ b/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv4/UDP.trp
@@ -0,0 +1 @@
+{"fileType":"trex-packet-editor","version":"1.0.0","metadata":{"caption":"ICMP echo request"},"packet":[{"id":"Ether","fields":[{"id":"type","value":"2048"}]},{"id":"IP","fields":[]},{"id":"UDP","fields":[]}],"fePrarameters":{"cache_size":"1000"},"feInstructions":[]} \ No newline at end of file
diff --git a/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv6/ICMP.trp b/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv6/ICMP.trp
new file mode 100644
index 00000000..c0387a0a
--- /dev/null
+++ b/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv6/ICMP.trp
@@ -0,0 +1 @@
+{"fileType":"trex-packet-editor","version":"1.0.0","metadata":{"caption":"ICMP echo request"},"packet":[{"id":"Ether","fields":[{"id":"type","value":"34525"}]},{"id":"IPv6","fields":[]},{"id":"ICMPv6ND_Redirect","fields":[]}],"fePrarameters":{"cache_size":"1000"},"feInstructions":[]} \ No newline at end of file
diff --git a/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv6/TCP.trp b/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv6/TCP.trp
new file mode 100644
index 00000000..1cb9576f
--- /dev/null
+++ b/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv6/TCP.trp
@@ -0,0 +1 @@
+{"fileType":"trex-packet-editor","version":"1.0.0","metadata":{"caption":"ICMP echo request"},"packet":[{"id":"Ether","fields":[{"id":"type","value":"34525"}]},{"id":"IPv6","fields":[]},{"id":"TCP","fields":[]}],"fePrarameters":{"cache_size":"1000"},"feInstructions":[]} \ No newline at end of file
diff --git a/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv6/UDP.trp b/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv6/UDP.trp
new file mode 100644
index 00000000..da96ae89
--- /dev/null
+++ b/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/IPv6/UDP.trp
@@ -0,0 +1 @@
+{"fileType":"trex-packet-editor","version":"1.0.0","metadata":{"caption":"ICMP echo request"},"packet":[{"id":"Ether","fields":[{"id":"type","value":"34525"}]},{"id":"IPv6","fields":[]},{"id":"UDP","fields":[]}],"fePrarameters":{"cache_size":"1000"},"feInstructions":[]} \ No newline at end of file
diff --git a/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/TCP-SYN.trp b/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/TCP-SYN.trp
new file mode 100644
index 00000000..8d7668cc
--- /dev/null
+++ b/scripts/automation/trex_control_plane/stl/services/scapy_server/templates/TCP-SYN.trp
@@ -0,0 +1 @@
+{"fileType":"trex-packet-editor","version":"1.0.0","metadata":{"caption":"TCP-SYN"},"packet":[{"id":"Ether","fields":[]},{"id":"IP","fields":[]},{"id":"TCP","fields":[{"id":"flags","value":""}]}],"fePrarameters":{"cache_size":"1000"},"feInstructions":[]} \ No newline at end of file
diff --git a/scripts/automation/trex_control_plane/stl/services/scapy_server/unit_tests/basetest.py b/scripts/automation/trex_control_plane/stl/services/scapy_server/unit_tests/basetest.py
index e48880e8..9836c794 100644
--- a/scripts/automation/trex_control_plane/stl/services/scapy_server/unit_tests/basetest.py
+++ b/scripts/automation/trex_control_plane/stl/services/scapy_server/unit_tests/basetest.py
@@ -88,3 +88,12 @@ def adapt_json_protocol_fields(protocols_array):
# change structure for easier
if protocol.get("fields"):
protocol["fields"] = fields_to_map(protocol["fields"])
+
+def get_templates():
+ return pass_result(service.get_templates(v_handler))
+
+
+
+def get_template(t):
+ return pass_result(service.get_template(v_handler, t))
+
diff --git a/scripts/automation/trex_control_plane/stl/services/scapy_server/unit_tests/test_scapy_service.py b/scripts/automation/trex_control_plane/stl/services/scapy_server/unit_tests/test_scapy_service.py
index e1094a79..1ece5d1e 100644
--- a/scripts/automation/trex_control_plane/stl/services/scapy_server/unit_tests/test_scapy_service.py
+++ b/scripts/automation/trex_control_plane/stl/services/scapy_server/unit_tests/test_scapy_service.py
@@ -289,3 +289,43 @@ def test_generate_vm_instructions():
ttl_instruction = res['field_engine']['instructions']['instructions'][2]
assert(ttl_instruction['min_value'] == 32)
assert(ttl_instruction['max_value'] == 64)
+
+
+def test_get_templates():
+ tt = get_templates()
+ assert(tt[0]['id'])
+ assert(tt[7]["meta"]['name'])
+ try:
+ assert(tt[9]['id'])
+ except:
+ pass
+
+
+def test_get_template():
+ tt = get_templates()
+ t = tt[0]
+ res = get_template(t)
+ res2 = base64.b64decode(res)
+ obj = json.loads(res2)
+ assert(obj['packet'][0]['id'] == 'Ether')
+ assert(obj['packet'][1]['id'] == 'IP')
+ assert(obj['packet'][2]['id'] == 'ICMP')
+
+
+def test_get_template2():
+ tt = get_templates()
+ t = tt[7]
+ res = get_template(t)
+ res2 = base64.b64decode(res)
+ obj = json.loads(res2)
+ assert(obj['packet'][0]['id'] == 'Ether')
+ assert(obj['packet'][1]['id'] == 'IPv6')
+ assert(obj['packet'][2]['id'] == 'UDP')
+
+
+def test_get_template3():
+ tt = get_templates()
+ t = tt[7]
+ t["id"] = "../../" + t["id"]
+ res = get_template(t)
+ assert(res == '')
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py
index c82d77fb..f7432107 100755
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py
@@ -452,16 +452,16 @@ class CCommLink(object):
if not self.virtual:
return self.rpc_link.disconnect()
- def transmit(self, method_name, params = None, api_class = 'core'):
+ def transmit(self, method_name, params = None, api_class = 'core', retry = 0):
if self.virtual:
self._prompt_virtual_tx_msg()
_, msg = self.rpc_link.create_jsonrpc_v2(method_name, params, api_class)
print(msg)
return
else:
- return self.rpc_link.invoke_rpc_method(method_name, params, api_class)
+ return self.rpc_link.invoke_rpc_method(method_name, params, api_class, retry = retry)
- def transmit_batch(self, batch_list):
+ def transmit_batch(self, batch_list, retry = 0):
if self.virtual:
self._prompt_virtual_tx_msg()
print([msg
@@ -472,7 +472,7 @@ class CCommLink(object):
for command in batch_list:
batch.add(command.method, command.params, command.api_class)
# invoke the batch
- return batch.invoke()
+ return batch.invoke(retry = retry)
def _prompt_virtual_tx_msg(self):
print("Transmitting virtually over tcp://{server}:{port}".format(server=self.server,
@@ -2322,7 +2322,7 @@ class STLClient(object):
@__api_check(True)
- def stop (self, ports = None, rx_delay_ms = 10):
+ def stop (self, ports = None, rx_delay_ms = None):
"""
Stop port(s)
@@ -2356,6 +2356,12 @@ class STLClient(object):
if not rc:
raise STLError(rc)
+ if rx_delay_ms is None:
+ if self.ports[ports[0]].is_virtual(): # assume all ports have same type
+ rx_delay_ms = 100
+ else:
+ rx_delay_ms = 10
+
# remove any RX filters
rc = self._remove_rx_filters(ports, rx_delay_ms = rx_delay_ms)
if not rc:
@@ -2827,7 +2833,7 @@ class STLClient(object):
@__api_check(True)
- def wait_on_traffic (self, ports = None, timeout = None, rx_delay_ms = 10):
+ def wait_on_traffic (self, ports = None, timeout = None, rx_delay_ms = None):
"""
.. _wait_on_traffic:
@@ -2871,6 +2877,12 @@ class STLClient(object):
if timer.has_expired():
raise STLTimeoutError(timeout)
+ if rx_delay_ms is None:
+ if self.ports[ports[0]].is_virtual(): # assume all ports have same type
+ rx_delay_ms = 100
+ else:
+ rx_delay_ms = 10
+
# remove any RX filters
rc = self._remove_rx_filters(ports, rx_delay_ms = rx_delay_ms)
if not rc:
@@ -2965,7 +2977,7 @@ class STLClient(object):
:parameters:
ports - which ports to resolve
- retires - how many times to retry on each port (intervals of 100 milliseconds)
+ retries - how many times to retry on each port (intervals of 100 milliseconds)
verbose - log for each request the response
:raises:
+ :exe:'STLError'
@@ -3835,7 +3847,7 @@ class STLClient(object):
parsing_opts.SUPPORTED,
)
- opts = parser.parse_args(line.split(), default_ports = self.get_acquired_ports(), verify_acquired = True)
+ opts = parser.parse_args(line.split(), default_ports = self.get_acquired_ports())
if not opts:
return opts
@@ -3845,8 +3857,9 @@ class STLClient(object):
opts.flow_ctrl = parsing_opts.FLOW_CTRL_DICT.get(opts.flow_ctrl)
# if no attributes - fall back to printing the status
- if not list(filter(lambda x:x is not None, [opts.prom, opts.link, opts.led, opts.flow_ctrl, opts.supp])):
- self.show_stats_line("--ps --port {0}".format(' '.join(str(port) for port in opts.ports)))
+ if not list(filter(lambda opt:opt[0] not in ('all_ports', 'ports') and opt[1] is not None, opts._get_kwargs())):
+ ports = opts.ports if opts.ports else self.get_all_ports()
+ self.show_stats_line("--ps --port {0}".format(' '.join(str(port) for port in ports)))
return
if opts.supp:
@@ -3859,11 +3872,13 @@ class STLClient(object):
print(' Flow control: %s' % info['fc_supported'])
print('')
else:
- self.set_port_attr(opts.ports,
- opts.prom,
- opts.link,
- opts.led,
- opts.flow_ctrl)
+ if not opts.ports:
+ raise STLError('No acquired ports!')
+ self.set_port_attr(opts.ports,
+ opts.prom,
+ opts.link,
+ opts.led,
+ opts.flow_ctrl)
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_jsonrpc_client.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_jsonrpc_client.py
index ff07b59a..db216532 100644
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_jsonrpc_client.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_jsonrpc_client.py
@@ -32,7 +32,7 @@ class BatchMessage(object):
id, msg = self.rpc_client.create_jsonrpc_v2(method_name, params, api_class, encode = False)
self.batch_list.append(msg)
- def invoke(self, block = False, chunk_size = 500000):
+ def invoke(self, block = False, chunk_size = 500000, retry = 0):
if not self.rpc_client.connected:
return RC_ERR("Not connected to server")
@@ -54,7 +54,7 @@ class BatchMessage(object):
return response_batch
else:
batch_json = json.dumps(self.batch_list)
- return self.rpc_client.send_msg(batch_json)
+ return self.rpc_client.send_msg(batch_json, retry = retry)
# JSON RPC v2.0 client
@@ -127,16 +127,16 @@ class JsonRpcClient(object):
return id, msg
- def invoke_rpc_method (self, method_name, params = None, api_class = 'core'):
+ def invoke_rpc_method (self, method_name, params = None, api_class = 'core', retry = 0):
if not self.connected:
return RC_ERR("Not connected to server")
id, msg = self.create_jsonrpc_v2(method_name, params, api_class)
- return self.send_msg(msg)
+ return self.send_msg(msg, retry = retry)
- def send_msg (self, msg):
+ def send_msg (self, msg, retry = 0):
# print before
if self.logger.check_verbose(self.logger.VERBOSE_HIGH):
self.verbose_msg("Sending Request To Server:\n\n" + self.pretty_json(msg) + "\n")
@@ -145,9 +145,9 @@ class JsonRpcClient(object):
buffer = msg.encode()
if self.zipper.check_threshold(buffer):
- response = self.send_raw_msg(self.zipper.compress(buffer))
+ response = self.send_raw_msg(self.zipper.compress(buffer), retry = retry)
else:
- response = self.send_raw_msg(buffer)
+ response = self.send_raw_msg(buffer, retry = retry)
if not response:
return response
@@ -175,16 +175,16 @@ class JsonRpcClient(object):
# low level send of string message
- def send_raw_msg (self, msg):
+ def send_raw_msg (self, msg, retry = 0):
- tries = 0
+ retry_left = retry
while True:
try:
self.socket.send(msg)
break
except zmq.Again:
- tries += 1
- if tries > 0:
+ retry_left -= 1
+ if retry_left < 0:
self.disconnect()
return RC_ERR("*** [RPC] - Failed to send message to server")
@@ -193,14 +193,14 @@ class JsonRpcClient(object):
self.reconnect()
raise e
- tries = 0
+ retry_left = retry
while True:
try:
response = self.socket.recv()
break
except zmq.Again:
- tries += 1
- if tries > 0:
+ retry_left -= 1
+ if retry_left < 0:
self.disconnect()
return RC_ERR("*** [RPC] - Failed to get server response from {0}".format(self.transport))
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py
index 654514cb..31d752af 100644
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py
@@ -267,7 +267,7 @@ class Port(object):
def add_streams (self, streams_list):
# listify
- streams_list = streams_list if isinstance(streams_list, list) else [streams_list]
+ streams_list = listify(streams_list)
lookup = {}
@@ -341,7 +341,7 @@ class Port(object):
def remove_streams (self, stream_id_list):
# single element to list
- stream_id_list = stream_id_list if isinstance(stream_id_list, list) else [stream_id_list]
+ stream_id_list = listify(stream_id_list)
# verify existance
if not all([stream_id in self.streams for stream_id in stream_id_list]):
@@ -736,7 +736,7 @@ class Port(object):
"slave_handler": slave_handler,
"min_ipg_usec": min_ipg_usec if min_ipg_usec else 0}
- rc = self.transmit("push_remote", params)
+ rc = self.transmit("push_remote", params, retry = 4)
if rc.bad():
return self.err(rc.err())
@@ -908,6 +908,10 @@ class Port(object):
def get_layer_cfg (self):
return self.__attr['layer_cfg']
+
+ def is_virtual(self):
+ return self.info.get('is_virtual')
+
def is_l3_mode (self):
return self.get_layer_cfg()['ipv4']['state'] != 'none'