summaryrefslogtreecommitdiffstats
path: root/scripts/automation/trex_control_plane/stl
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2016-05-08 10:57:57 +0300
committerimarom <imarom@cisco.com>2016-05-09 16:48:15 +0300
commit75ce59e5652f9094beab854d263a850cfc81a3de (patch)
tree10e7216b433aaae1888850a59f48e9c1df84af65 /scripts/automation/trex_control_plane/stl
parent8691f4019dc2123c1aa7413cf3666138756c2f66 (diff)
PCAP refinement
Diffstat (limited to 'scripts/automation/trex_control_plane/stl')
-rwxr-xr-xscripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_client.py25
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_port.py222
-rwxr-xr-xscripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py2
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/text_opts.py12
4 files changed, 137 insertions, 124 deletions
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 c7d59690..0d95131f 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
@@ -335,30 +335,37 @@ class EventsHandler(object):
# private functions
+ # on rare cases events may come on a non existent prot
+ # (server was re-run with different config)
def __async_event_port_job_done (self, port_id):
- self.client.ports[port_id].async_event_port_job_done()
+ if port_id in self.client.ports:
+ self.client.ports[port_id].async_event_port_job_done()
def __async_event_port_stopped (self, port_id):
- self.client.ports[port_id].async_event_port_stopped()
+ if port_id in self.client.ports:
+ self.client.ports[port_id].async_event_port_stopped()
def __async_event_port_started (self, port_id):
- self.client.ports[port_id].async_event_port_started()
-
+ if port_id in self.client.ports:
+ self.client.ports[port_id].async_event_port_started()
def __async_event_port_paused (self, port_id):
- self.client.ports[port_id].async_event_port_paused()
+ if port_id in self.client.ports:
+ self.client.ports[port_id].async_event_port_paused()
def __async_event_port_resumed (self, port_id):
- self.client.ports[port_id].async_event_port_resumed()
-
+ if port_id in self.client.ports:
+ self.client.ports[port_id].async_event_port_resumed()
def __async_event_port_acquired (self, port_id, who):
- self.client.ports[port_id].async_event_acquired(who)
+ if port_id in self.client.ports:
+ self.client.ports[port_id].async_event_acquired(who)
def __async_event_port_released (self, port_id):
- self.client.ports[port_id].async_event_released()
+ if port_id in self.client.ports:
+ self.client.ports[port_id].async_event_released()
def __async_event_server_stopped (self):
self.client.connected = False
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 986cb3c6..43fc29e6 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
@@ -29,17 +29,20 @@ def mult_to_factor (mult, max_bps_l2, max_pps, line_util):
# describes a single port
class Port(object):
- STATE_DOWN = 0
- STATE_IDLE = 1
- STATE_STREAMS = 2
- STATE_TX = 3
- STATE_PAUSE = 4
+ STATE_DOWN = 0
+ STATE_IDLE = 1
+ STATE_STREAMS = 2
+ STATE_TX = 3
+ STATE_PAUSE = 4
+ STATE_PCAP_TX = 5
+
PortState = namedtuple('PortState', ['state_id', 'state_name'])
STATES_MAP = {STATE_DOWN: "DOWN",
STATE_IDLE: "IDLE",
STATE_STREAMS: "IDLE",
STATE_TX: "ACTIVE",
- STATE_PAUSE: "PAUSE"}
+ STATE_PAUSE: "PAUSE",
+ STATE_PCAP_TX : "ACTIVE"}
def __init__ (self, port_id, user, comm_link, session_id, info):
@@ -67,6 +70,54 @@ class Port(object):
self.owner = ''
+ # decorator to verify port is up
+ def up(func):
+ def func_wrapper(*args):
+ port = args[0]
+
+ if not port.is_up():
+ return port.err("{0} - port is down".format(func.__name__))
+
+ return func(*args)
+
+ return func_wrapper
+
+ # owned
+ def owned(func):
+ def func_wrapper(*args):
+ port = args[0]
+
+ if not port.is_up():
+ return port.err("{0} - port is down".format(func.__name__))
+
+ if not port.is_acquired():
+ return port.err("{0} - port is not owned".format(func.__name__))
+
+ return func(*args)
+
+ return func_wrapper
+
+
+ # decorator to check server is readable (port not down and etc.)
+ def writeable(func):
+ def func_wrapper(*args):
+ port = args[0]
+
+ if not port.is_up():
+ return port.err("{0} - port is down".format(func.__name__))
+
+ if not port.is_acquired():
+ return port.err("{0} - port is not owned".format(func.__name__))
+
+ if not port.is_writeable():
+ return port.err("{0} - port is not in a writeable state".format(func.__name__))
+
+ return func(*args)
+
+ return func_wrapper
+
+
+
def err(self, msg):
return RC_ERR("port {0} : {1}\n".format(self.port_id, msg))
@@ -79,7 +130,39 @@ class Port(object):
def get_formatted_speed (self):
return "{0} Gbps".format(self.info['speed'])
+ def is_acquired(self):
+ return (self.handler != None)
+
+ def is_up (self):
+ return (self.state != self.STATE_DOWN)
+
+ def is_active(self):
+ return (self.state == self.STATE_TX ) or (self.state == self.STATE_PAUSE) or (self.state == self.STATE_PCAP_TX)
+
+ def is_transmitting (self):
+ return (self.state == self.STATE_TX) or (self.state == self.STATE_PCAP_TX)
+
+ def is_paused (self):
+ return (self.state == self.STATE_PAUSE)
+
+ def is_writeable (self):
+ # operations on port can be done on state idle or state streams
+ return ((self.state == self.STATE_IDLE) or (self.state == self.STATE_STREAMS))
+
+ def get_owner (self):
+ if self.is_acquired():
+ return self.user
+ else:
+ return self.owner
+
+ def __allocate_stream_id (self):
+ id = self.next_available_id
+ self.next_available_id += 1
+ return id
+
+
# take the port
+ @up
def acquire(self, force = False, sync_streams = True):
params = {"port_id": self.port_id,
"user": self.user,
@@ -99,6 +182,7 @@ class Port(object):
# sync all the streams with the server
+ @up
def sync_streams (self):
params = {"port_id": self.port_id}
@@ -114,6 +198,7 @@ class Port(object):
return self.ok()
# release the port
+ @up
def release(self):
params = {"port_id": self.port_id,
"handler": self.handler}
@@ -129,24 +214,9 @@ class Port(object):
else:
return self.err(rc.err())
- def is_acquired(self):
- return (self.handler != None)
-
- def is_active(self):
- return(self.state == self.STATE_TX ) or (self.state == self.STATE_PAUSE)
-
- def is_transmitting (self):
- return (self.state == self.STATE_TX)
-
- def is_paused (self):
- return (self.state == self.STATE_PAUSE)
-
- def get_owner (self):
- if self.is_acquired():
- return self.user
- else:
- return self.owner
+
+ @up
def sync(self):
params = {"port_id": self.port_id}
@@ -168,6 +238,8 @@ class Port(object):
self.state = self.STATE_TX
elif port_state == "PAUSE":
self.state = self.STATE_PAUSE
+ elif port_state == "PCAP_TX":
+ self.state = self.STATE_PCAP_TX
else:
raise Exception("port {0}: bad state received from server '{1}'".format(self.port_id, port_state))
@@ -182,27 +254,11 @@ class Port(object):
return self.ok()
- # return TRUE if write commands
- def is_port_writable (self):
- # operations on port can be done on state idle or state streams
- return ((self.state == self.STATE_IDLE) or (self.state == self.STATE_STREAMS))
-
-
- def __allocate_stream_id (self):
- id = self.next_available_id
- self.next_available_id += 1
- return id
-
# add streams
+ @writeable
def add_streams (self, streams_list):
- if not self.is_acquired():
- return self.err("port is not owned")
-
- if not self.is_port_writable():
- return self.err("Please stop port before attempting to add streams")
-
# listify
streams_list = streams_list if isinstance(streams_list, list) else [streams_list]
@@ -274,14 +330,9 @@ class Port(object):
# remove stream from port
+ @writeable
def remove_streams (self, stream_id_list):
- if not self.is_acquired():
- return self.err("port is not owned")
-
- if not self.is_port_writable():
- return self.err("Please stop port before attempting to remove streams")
-
# single element to list
stream_id_list = stream_id_list if isinstance(stream_id_list, list) else [stream_id_list]
@@ -315,14 +366,9 @@ class Port(object):
# remove all the streams
+ @writeable
def remove_all_streams (self):
- if not self.is_acquired():
- return self.err("port is not owned")
-
- if not self.is_port_writable():
- return self.err("Please stop port before attempting to remove streams")
-
params = {"handler": self.handler,
"port_id": self.port_id}
@@ -349,19 +395,11 @@ class Port(object):
return self.streams
- # start traffic
+ @writeable
def start (self, mul, duration, force):
- if not self.is_acquired():
- return self.err("port is not owned")
-
- if self.state == self.STATE_DOWN:
- return self.err("Unable to start traffic - port is down")
if self.state == self.STATE_IDLE:
- return self.err("Unable to start traffic - no streams attached to port")
-
- if self.state == self.STATE_TX:
- return self.err("Unable to start traffic - port is already transmitting")
+ return self.err("unable to start traffic - no streams attached to port")
params = {"handler": self.handler,
"port_id": self.port_id,
@@ -379,15 +417,12 @@ class Port(object):
# stop traffic
# with force ignores the cached state and sends the command
+ @owned
def stop (self, force = False):
- if not self.is_acquired():
- return self.err("port is not owned")
-
- # port is already stopped
- if not force:
- if (self.state == self.STATE_IDLE) or (self.state == self.state == self.STATE_STREAMS):
- return self.ok()
+ # if not is not active and not force - go back
+ if not self.is_active() and not force:
+ return self.ok()
params = {"handler": self.handler,
"port_id": self.port_id}
@@ -421,19 +456,10 @@ class Port(object):
return not self.tx_stopped_ts or (datetime.now() - self.tx_stopped_ts) > timedelta(milliseconds = rx_delay_ms)
-
+ @writeable
def remove_rx_filters (self):
assert(self.has_rx_enabled())
- if not self.is_acquired():
- return self.err("port is not owned")
-
- if self.state == self.STATE_DOWN:
- return self.err("Unable to remove RX filters - port is down")
-
- if self.state == self.STATE_TX:
- return self.err("Unable to remove RX filters - port is transmitting")
-
if self.state == self.STATE_IDLE:
return self.ok()
@@ -447,12 +473,9 @@ class Port(object):
return self.ok()
-
+ @owned
def pause (self):
- if not self.is_acquired():
- return self.err("port is not owned")
-
if (self.state != self.STATE_TX) :
return self.err("port is not transmitting")
@@ -467,12 +490,9 @@ class Port(object):
return self.ok()
-
+ @owned
def resume (self):
- if not self.is_acquired():
- return self.err("port is not owned")
-
if (self.state != self.STATE_PAUSE) :
return self.err("port is not in pause mode")
@@ -489,12 +509,9 @@ class Port(object):
return self.ok()
-
+ @owned
def update (self, mul, force):
- if not self.is_acquired():
- return self.err("port is not owned")
-
if (self.state != self.STATE_TX) :
return self.err("port is not transmitting")
@@ -509,15 +526,9 @@ class Port(object):
return self.ok()
-
+ @owned
def validate (self):
- if not self.is_acquired():
- return self.err("port is not owned")
-
- if (self.state == self.STATE_DOWN):
- return self.err("port is down")
-
if (self.state == self.STATE_IDLE):
return self.err("no streams attached to port")
@@ -533,12 +544,8 @@ class Port(object):
return self.ok()
+ @owned
def set_attr (self, attr_dict):
- if not self.is_acquired():
- return self.err("port is not owned")
-
- if (self.state == self.STATE_DOWN):
- return self.err("port is down")
params = {"handler": self.handler,
"port_id": self.port_id,
@@ -553,13 +560,8 @@ class Port(object):
return self.ok()
-
+ @writeable
def push_remote (self, pcap_filename, ipg_usec, speedup, count):
- if not self.is_acquired():
- return self.err("port is not owned")
-
- if (self.state == self.STATE_DOWN):
- return self.err("port is down")
params = {"handler": self.handler,
"port_id": self.port_id,
@@ -572,7 +574,7 @@ class Port(object):
if rc.bad():
return self.err(rc.err())
- self.state = self.STATE_TX
+ self.state = self.STATE_PCAP_TX
return self.ok()
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py
index 6ee587c3..66aeaef4 100755
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_streams.py
@@ -939,7 +939,7 @@ class STLProfile(object):
Name of the pcap file
ipg_usec : float
- Inter packet gap in usec. If IPG=0, IPG is taken from pcap file
+ Inter packet gap in usec. If IPG is None, IPG is taken from pcap file
speedup : float
When reading the pcap file, divide IPG by this "speedup" factor. Resulting IPG is sped up by this factor.
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/text_opts.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/text_opts.py
index 5c0dfb14..7e0bf9e4 100644
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/text_opts.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/text_opts.py
@@ -150,11 +150,15 @@ def format_text(text, *args):
def format_threshold (value, red_zone, green_zone):
- if value >= red_zone[0] and value <= red_zone[1]:
- return format_text("{0}".format(value), 'red')
+ try:
+ if value >= red_zone[0] and value <= red_zone[1]:
+ return format_text("{0}".format(value), 'red')
- if value >= green_zone[0] and value <= green_zone[1]:
- return format_text("{0}".format(value), 'green')
+ if value >= green_zone[0] and value <= green_zone[1]:
+ return format_text("{0}".format(value), 'green')
+ except TypeError:
+ # if value is not comparable or not a number - skip this
+ pass
return "{0}".format(value)