From 75ce59e5652f9094beab854d263a850cfc81a3de Mon Sep 17 00:00:00 2001 From: imarom Date: Sun, 8 May 2016 10:57:57 +0300 Subject: PCAP refinement --- .../stl/trex_stl_lib/trex_stl_client.py | 25 ++- .../stl/trex_stl_lib/trex_stl_port.py | 222 +++++++++++---------- .../stl/trex_stl_lib/trex_stl_streams.py | 2 +- .../stl/trex_stl_lib/utils/text_opts.py | 12 +- 4 files changed, 137 insertions(+), 124 deletions(-) (limited to 'scripts/automation/trex_control_plane/stl') 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) -- cgit 1.2.3-korg