From c227a2fff3e815c38cff89630e22c3b8485c32de Mon Sep 17 00:00:00 2001
From: imarom <imarom@cisco.com>
Date: Mon, 2 May 2016 16:35:17 +0300
Subject: two fixes: 1. history traversal with lock when adding stats objects
 2. sync with ports only when you acquire the port, reset does not sync with
 the streams

---
 .../stl/trex_stl_lib/trex_stl_client.py            | 15 +++++---
 .../stl/trex_stl_lib/trex_stl_port.py              | 42 +++++++++++++---------
 .../stl/trex_stl_lib/trex_stl_stats.py             | 13 +++----
 3 files changed, 42 insertions(+), 28 deletions(-)

(limited to 'scripts/automation/trex_control_plane')

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 864e00ad..862a9979 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
@@ -582,13 +582,13 @@ class STLClient(object):
         return rc
 
     # acquire ports, if port_list is none - get all
-    def __acquire (self, port_id_list = None, force = False):
+    def __acquire (self, port_id_list = None, force = False, sync_streams = True):
         port_id_list = self.__ports(port_id_list)
 
         rc = RC()
 
         for port_id in port_id_list:
-            rc.add(self.ports[port_id].acquire(force))
+            rc.add(self.ports[port_id].acquire(force, sync_streams))
 
         return rc
 
@@ -1372,16 +1372,20 @@ class STLClient(object):
 
 
     @__api_check(True)
-    def acquire (self, ports = None, force = False):
+    def acquire (self, ports = None, force = False, sync_streams = True):
         """
             Acquires ports for executing commands
 
             :parameters:
                 ports : list
                     Ports on which to execute the command
+
                 force : bool
                     Force acquire the ports.
 
+                sync_streams: bool
+                    sync with the server about the configured streams
+
             :raises:
                 + :exc:`STLError`
 
@@ -1396,7 +1400,7 @@ class STLClient(object):
         else:
             self.logger.pre_cmd("Acquiring ports {0}:".format(ports))
 
-        rc = self.__acquire(ports, force)
+        rc = self.__acquire(ports, force, sync_streams)
 
         self.logger.post_cmd(rc)
 
@@ -1496,7 +1500,8 @@ class STLClient(object):
         ports = ports if ports is not None else self.get_all_ports()
         ports = self._validate_port_list(ports)
 
-        self.acquire(ports, force = True)
+        # force take the port and ignore any streams on it
+        self.acquire(ports, force = True, sync_streams = False)
         self.stop(ports, rx_delay_ms = 0)
         self.remove_all_streams(ports)
         self.clear_stats(ports)
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 5cf94bda..e8f89b27 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
@@ -80,19 +80,39 @@ class Port(object):
         return "{0} Gbps".format(self.info['speed'])
 
     # take the port
-    def acquire(self, force = False):
+    def acquire(self, force = False, sync_streams = True):
         params = {"port_id":     self.port_id,
                   "user":        self.user,
                   "session_id":  self.session_id,
                   "force":       force}
 
         rc = self.transmit("acquire", params)
-        if rc.good():
-            self.handler = rc.data()
-            return self.ok()
+        if not rc:
+            return self.err(rc.err())
+
+        self.handler = rc.data()
+
+        if sync_streams:
+            return self.sync_streams()
         else:
+            return self.ok()
+
+      
+    # sync all the streams with the server
+    def sync_streams (self):
+        params = {"port_id": self.port_id}
+
+        rc = self.transmit("get_all_streams", params)
+        if rc.bad():
             return self.err(rc.err())
 
+        for k, v in rc.data()['streams'].items():
+            self.streams[k] = {'next_id': v['next_stream_id'],
+                               'pkt'    : base64.b64decode(v['packet']['binary']),
+                               'mode'   : v['mode']['type'],
+                               'rate'   : STLStream.get_rate_from_field(v['mode']['rate'])}
+        return self.ok()
+
     # release the port
     def release(self):
         params = {"port_id": self.port_id,
@@ -157,19 +177,7 @@ class Port(object):
         # attributes
         self.attr = rc.data()['attr']
 
-        # sync the streams
-        params = {"port_id": self.port_id}
-
-        rc = self.transmit("get_all_streams", params)
-        if rc.bad():
-            return self.err(rc.err())
-
-        for k, v in rc.data()['streams'].items():
-            self.streams[k] = {'next_id': v['next_stream_id'],
-                               'pkt'    : base64.b64decode(v['packet']['binary']),
-                               'mode'   : v['mode']['type'],
-                               'rate'   : STLStream.get_rate_from_field(v['mode']['rate'])}
-
+     
         return self.ok()
 
 
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py
index 42bef360..12c2c578 100644
--- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_stats.py
@@ -698,12 +698,13 @@ class CPortStats(CTRexStats):
             else:
                 self.__merge_dicts(self.reference_stats, x.reference_stats)
 
-        # history
-        if not self.history:
-            self.history = copy.deepcopy(x.history)
-        else:
-            for h1, h2 in zip(self.history, x.history):
-                self.__merge_dicts(h1, h2)
+        # history - should be traverse with a lock
+        with self.lock, x.lock:
+            if not self.history:
+                self.history = copy.deepcopy(x.history)
+            else:
+                for h1, h2 in zip(self.history, x.history):
+                    self.__merge_dicts(h1, h2)
 
         return self
 
-- 
cgit