From 0c5a4348a31e0e8d76dd1fcf378cb2c0a2867f59 Mon Sep 17 00:00:00 2001
From: Dan Klein <danklein10@gmail.com>
Date: Thu, 15 Oct 2015 09:57:35 +0300
Subject: updated yaml utils and stream object

---
 .../trex_control_plane/common/trex_streams.py      | 190 +++++++++++++++++++++
 1 file changed, 190 insertions(+)
 create mode 100644 scripts/automation/trex_control_plane/common/trex_streams.py

(limited to 'scripts/automation/trex_control_plane/common/trex_streams.py')

diff --git a/scripts/automation/trex_control_plane/common/trex_streams.py b/scripts/automation/trex_control_plane/common/trex_streams.py
new file mode 100644
index 00000000..3b0e7376
--- /dev/null
+++ b/scripts/automation/trex_control_plane/common/trex_streams.py
@@ -0,0 +1,190 @@
+#!/router/bin/python
+
+import external_packages
+from client_utils.packet_builder import CTRexPktBuilder
+from collections import OrderedDict
+
+
+class CStreamList(object):
+
+    def __init__(self):
+        self.streams_list = OrderedDict()
+        self._stream_id = 0
+        # self._stream_by_name = {}
+
+    def append_stream(self, name, stream_obj):
+        assert isinstance(stream_obj, CStream)
+        if name in self.streams_list:
+            raise NameError("A stream with this name already exists on this list.")
+        self.streams_list[name]=stream_obj
+        return
+
+    def remove_stream(self, name):
+        return self.streams_list.pop(name)
+
+    def export_to_yaml(self, file_path):
+        pass
+
+    def load_yaml(self, file_path):
+        # clear all existing streams linked to this object
+        self.streams_list.clear()
+        # self._stream_id = 0
+        # load from YAML file the streams one by one
+        try:
+            with open(file_path, 'r') as f:
+                loaded_streams = yaml.load(f)
+
+                # assume at this point that YAML file is according to rules and correct
+
+
+        except yaml.YAMLError as e:
+            print "Error in YAML configuration file:", e
+            print "Aborting YAML loading, no changes made to stream list"
+            return
+
+
+        pass
+
+
+
+
+class CStream(object):
+    """docstring for CStream"""
+    DEFAULTS = {"rx_stats": CRxStats,
+                "mode": CTxMode,
+                "isg": 5.0,
+                "next_stream": -1,
+                "self_start": True,
+                "enabled": True}
+
+    def __init__(self, **kwargs):
+        super(CStream, self).__init__()
+        for k, v in kwargs.items():
+            setattr(self, k, v)
+        # set default values to unset attributes, according to DEFAULTS dict
+        set_keys = set(kwargs.keys())
+        keys_to_set = [x
+                       for x in self.DEFAULTS
+                       if x not in set_keys]
+        for key in keys_to_set:
+            default = self.DEFAULTS.get(key)
+            if type(default) == type:
+                setattr(self, key, default())
+            else:
+                setattr(self, key, default)
+
+    @property
+    def packet(self):
+        return self._packet
+
+    @packet.setter
+    def packet(self, packet_obj):
+        assert isinstance(packet_obj, CTRexPktBuilder)
+        self._packet = packet_obj
+
+    @property
+    def enabled(self):
+        return self._enabled
+
+    @enabled.setter
+    def enabled(self, bool_value):
+        self._enabled = bool(bool_value)
+
+    @property
+    def self_start(self):
+        return self._self_start
+
+    @self_start.setter
+    def self_start(self, bool_value):
+        self._self_start = bool(bool_value)
+
+    @property
+    def next_stream(self):
+        return self._next_stream
+
+    @next_stream.setter
+    def next_stream(self, value):
+        self._next_stream = int(value)
+
+    def dump(self):
+        pass
+        return {"enabled": self.enabled,
+                "self_start": self.self_start,
+                "isg": self.isg,
+                "next_stream": self.next_stream,
+                "packet": self.packet.dump_pkt(),
+                "mode": self.mode.dump(),
+                "vm": self.packet.get_vm_data(),
+                "rx_stats": self.rx_stats.dump()}
+
+class CRxStats(object):
+
+    def __init__(self, enabled=False, seq_enabled=False, latency_enabled=False):
+        self._rx_dict = {"enabled": enabled,
+                         "seq_enabled": seq_enabled,
+                         "latency_enabled": latency_enabled}
+
+    @property
+    def enabled(self):
+        return self._rx_dict.get("enabled")
+
+    @enabled.setter
+    def enabled(self, bool_value):
+        self._rx_dict['enabled'] = bool(bool_value)
+
+    @property
+    def seq_enabled(self):
+        return self._rx_dict.get("seq_enabled")
+
+    @seq_enabled.setter
+    def seq_enabled(self, bool_value):
+        self._rx_dict['seq_enabled'] = bool(bool_value)
+
+    @property
+    def latency_enabled(self):
+        return self._rx_dict.get("latency_enabled")
+
+    @latency_enabled.setter
+    def latency_enabled(self, bool_value):
+        self._rx_dict['latency_enabled'] = bool(bool_value)
+
+    def dump(self):
+        return {k: v
+                for k, v in self._rx_dict.items()
+                if v
+                }
+
+
+class CTxMode(object):
+    """docstring for CTxMode"""
+    def __init__(self, tx_mode, pps):
+        super(CTxMode, self).__init__()
+        if tx_mode not in ["continuous", "single_burst", "multi_burst"]:
+            raise ValueError("Unknown TX mode ('{0}')has been initialized.".format(tx_mode))
+        self._tx_mode = tx_mode
+        self._fields = {'pps': float(pps)}
+        if tx_mode == "single_burst":
+            self._fields['total_pkts'] = 0
+        elif tx_mode == "multi_burst":
+            self._fields['pkts_per_burst'] = 0
+            self._fields['ibg'] = 0.0
+            self._fields['count'] = 0
+        else:
+            pass
+
+    def set_tx_mode_attr(self, attr, val):
+        if attr in self._fields:
+            self._fields[attr] = type(self._fields.get(attr))(val)
+        else:
+            raise ValueError("The provided attribute ('{0}') is not a legal attribute in selected TX mode ('{1}')".
+                             format(attr, self._tx_mode))
+
+    def dump(self):
+        dump = {"type": self._tx_mode}
+        dump.update({k: v
+                     for k, v in self._fields.items()
+                     })
+        return dump
+
+if __name__ == "__main__":
+    pass
-- 
cgit 


From 4a8d34c7548e85e97426bc1d85c670003b1f5870 Mon Sep 17 00:00:00 2001
From: Dan Klein <danklein10@gmail.com>
Date: Sun, 18 Oct 2015 10:24:53 +0300
Subject: more yaml utils, better streams handling

---
 .../trex_control_plane/common/trex_streams.py      | 230 +++++++++++++--------
 1 file changed, 145 insertions(+), 85 deletions(-)

(limited to 'scripts/automation/trex_control_plane/common/trex_streams.py')

diff --git a/scripts/automation/trex_control_plane/common/trex_streams.py b/scripts/automation/trex_control_plane/common/trex_streams.py
index 3b0e7376..e6aa66f2 100644
--- a/scripts/automation/trex_control_plane/common/trex_streams.py
+++ b/scripts/automation/trex_control_plane/common/trex_streams.py
@@ -3,12 +3,15 @@
 import external_packages
 from client_utils.packet_builder import CTRexPktBuilder
 from collections import OrderedDict
+from client_utils.yaml_utils import *
+import dpkt
 
 
 class CStreamList(object):
 
     def __init__(self):
         self.streams_list = OrderedDict()
+        self.yaml_loader = CTRexYAMLLoader("rpc_exceptions.yaml")
         self._stream_id = 0
         # self._stream_by_name = {}
 
@@ -22,101 +25,50 @@ class CStreamList(object):
     def remove_stream(self, name):
         return self.streams_list.pop(name)
 
+    def rearrange_streams(self, streams_names_list, new_streams_dict={}):
+        tmp_list = OrderedDict()
+        for stream in streams_names_list:
+            if stream in self.streams_list:
+                tmp_list[stream] = self.streams_list.get(stream)
+            elif stream in new_streams_dict:
+                new_stream_obj = new_streams_dict.get(stream)
+                assert isinstance(new_stream_obj, CStream)
+                tmp_list[stream] = new_stream_obj
+            else:
+                raise NameError("Given stream named '{0}' cannot be found in existing stream list or and wasn't"
+                                "provided with the new_stream_dict parameter.".format(stream))
+        self.streams_list = tmp_list
+
     def export_to_yaml(self, file_path):
-        pass
+        raise NotImplementedError("export_to_yaml method is not implemented, yet")
 
-    def load_yaml(self, file_path):
+    def load_yaml(self, file_path, multiplier_dict={}):
         # clear all existing streams linked to this object
         self.streams_list.clear()
-        # self._stream_id = 0
-        # load from YAML file the streams one by one
-        try:
-            with open(file_path, 'r') as f:
-                loaded_streams = yaml.load(f)
+        streams_data = load_yaml_to_obj(file_path)
+        assert isinstance(streams_data, list)
+        raw_streams = {}
+        for stream in streams_data:
+            stream_name = stream.get("name")
+            raw_stream = stream.get("stream")
+            if not stream_name or not raw_stream:
+                raise ValueError("Provided stream is not according to convention."
+                                 "Each stream must be provided as two keys: 'name' and 'stream'. "
+                                 "Provided item was:\n {stream}".format(stream))
+            new_stream_data = self.yaml_loader.validate_yaml(raw_stream,
+                                                             "stream",
+                                                             multiplier= multiplier_dict.get(stream_name, 1))
+            new_stream_obj = CStream()
+            new_stream_obj.load_data(**new_stream_data)
+            self.append_stream(stream_name, new_stream_obj)
 
-                # assume at this point that YAML file is according to rules and correct
 
 
-        except yaml.YAMLError as e:
-            print "Error in YAML configuration file:", e
-            print "Aborting YAML loading, no changes made to stream list"
-            return
+        # start validating and reassembling clients input
 
 
         pass
 
-
-
-
-class CStream(object):
-    """docstring for CStream"""
-    DEFAULTS = {"rx_stats": CRxStats,
-                "mode": CTxMode,
-                "isg": 5.0,
-                "next_stream": -1,
-                "self_start": True,
-                "enabled": True}
-
-    def __init__(self, **kwargs):
-        super(CStream, self).__init__()
-        for k, v in kwargs.items():
-            setattr(self, k, v)
-        # set default values to unset attributes, according to DEFAULTS dict
-        set_keys = set(kwargs.keys())
-        keys_to_set = [x
-                       for x in self.DEFAULTS
-                       if x not in set_keys]
-        for key in keys_to_set:
-            default = self.DEFAULTS.get(key)
-            if type(default) == type:
-                setattr(self, key, default())
-            else:
-                setattr(self, key, default)
-
-    @property
-    def packet(self):
-        return self._packet
-
-    @packet.setter
-    def packet(self, packet_obj):
-        assert isinstance(packet_obj, CTRexPktBuilder)
-        self._packet = packet_obj
-
-    @property
-    def enabled(self):
-        return self._enabled
-
-    @enabled.setter
-    def enabled(self, bool_value):
-        self._enabled = bool(bool_value)
-
-    @property
-    def self_start(self):
-        return self._self_start
-
-    @self_start.setter
-    def self_start(self, bool_value):
-        self._self_start = bool(bool_value)
-
-    @property
-    def next_stream(self):
-        return self._next_stream
-
-    @next_stream.setter
-    def next_stream(self, value):
-        self._next_stream = int(value)
-
-    def dump(self):
-        pass
-        return {"enabled": self.enabled,
-                "self_start": self.self_start,
-                "isg": self.isg,
-                "next_stream": self.next_stream,
-                "packet": self.packet.dump_pkt(),
-                "mode": self.mode.dump(),
-                "vm": self.packet.get_vm_data(),
-                "rx_stats": self.rx_stats.dump()}
-
 class CRxStats(object):
 
     def __init__(self, enabled=False, seq_enabled=False, latency_enabled=False):
@@ -154,7 +106,6 @@ class CRxStats(object):
                 if v
                 }
 
-
 class CTxMode(object):
     """docstring for CTxMode"""
     def __init__(self, tx_mode, pps):
@@ -186,5 +137,114 @@ class CTxMode(object):
                      })
         return dump
 
+class CStream(object):
+    """docstring for CStream"""
+    DEFAULTS = {"rx_stats": CRxStats,
+                "mode": CTxMode,
+                "isg": 5.0,
+                "next_stream": -1,
+                "self_start": True,
+                "enabled": True}
+
+    FIELDS = ["enabled", "self_start", "next_stream", "isg", "mode", "rx_stats", "packet", "vm"]
+
+    def __init__(self):
+        super(CStream, self).__init__()
+        for field in CStream.FIELDS:
+            setattr(self, field, None)
+
+    def load_data(self, **kwargs):
+        for k, v in kwargs.items():
+            if k == "rx_stats":
+                if isinstance(v, dict):
+                    setattr(self, k, CRxStats(**v))
+                elif isinstance(v, CRxStats):
+                    setattr(self, k, v)
+            elif k == "mode":
+                if isinstance(v, dict):
+                    setattr(self, k, CTxMode(v))
+                elif isinstance(v, CTxMode):
+                    setattr(self, k, v)
+            else:
+                setattr(self, k, v)
+
+
+
+    # def __init__(self, enabled, self_start, next_stream, isg, mode, rx_stats, packet, vm):
+    #     super(CStream, self).__init__()
+    #     for k, v in kwargs.items():
+    #         if k == "rx_stats":
+    #             if isinstance(v, dict):
+    #                 setattr(self, k, CRxStats(v))
+    #             elif isinstance(v, CRxStats):
+    #                 setattr(self, k, v)
+    #         elif k == "mode":
+    #             if isinstance(v, dict):
+    #                 setattr(self, k, CTxMode(v))
+    #             elif isinstance(v, CTxMode):
+    #                 setattr(self, k, v)
+    #         else:
+    #             setattr(self, k, v)
+    #     # set default values to unset attributes, according to DEFAULTS dict
+    #     set_keys = set(kwargs.keys())
+    #     keys_to_set = [x
+    #                    for x in self.DEFAULTS
+    #                    if x not in set_keys]
+    #     for key in keys_to_set:
+    #         default = self.DEFAULTS.get(key)
+    #         if type(default) == type:
+    #             setattr(self, key, default())
+    #         else:
+    #             setattr(self, key, default)
+
+    # @property
+    # def packet(self):
+    #     return self._packet
+    #
+    # @packet.setter
+    # def packet(self, packet_obj):
+    #     assert isinstance(packet_obj, CTRexPktBuilder)
+    #     self._packet = packet_obj
+    #
+    # @property
+    # def enabled(self):
+    #     return self._enabled
+    #
+    # @enabled.setter
+    # def enabled(self, bool_value):
+    #     self._enabled = bool(bool_value)
+    #
+    # @property
+    # def self_start(self):
+    #     return self._self_start
+    #
+    # @self_start.setter
+    # def self_start(self, bool_value):
+    #     self._self_start = bool(bool_value)
+    #
+    # @property
+    # def next_stream(self):
+    #     return self._next_stream
+    #
+    # @next_stream.setter
+    # def next_stream(self, value):
+    #     self._next_stream = int(value)
+
+    def dump(self):
+        pass
+        return {"enabled": self.enabled,
+                "self_start": self.self_start,
+                "isg": self.isg,
+                "next_stream": self.next_stream,
+                "packet": self.packet.dump_pkt(),
+                "mode": self.mode.dump(),
+                "vm": self.packet.get_vm_data(),
+                "rx_stats": self.rx_stats.dump()}
+
+
+
+
+
+
 if __name__ == "__main__":
     pass
-- 
cgit 


From 80bd7895112cba0b3cbb6d56995def6ffbdccf33 Mon Sep 17 00:00:00 2001
From: Dan Klein <danklei@cisco.com>
Date: Sun, 18 Oct 2015 16:12:26 +0300
Subject: Progress in trex_streams and in yaml_utils. Next, start working on
 StreamList object

---
 .../trex_control_plane/common/trex_streams.py      | 274 +++++++++------------
 1 file changed, 123 insertions(+), 151 deletions(-)
 mode change 100644 => 100755 scripts/automation/trex_control_plane/common/trex_streams.py

(limited to 'scripts/automation/trex_control_plane/common/trex_streams.py')

diff --git a/scripts/automation/trex_control_plane/common/trex_streams.py b/scripts/automation/trex_control_plane/common/trex_streams.py
old mode 100644
new mode 100755
index e6aa66f2..e366001d
--- a/scripts/automation/trex_control_plane/common/trex_streams.py
+++ b/scripts/automation/trex_control_plane/common/trex_streams.py
@@ -5,13 +5,14 @@ from client_utils.packet_builder import CTRexPktBuilder
 from collections import OrderedDict
 from client_utils.yaml_utils import *
 import dpkt
+import struct
 
 
 class CStreamList(object):
 
     def __init__(self):
-        self.streams_list = OrderedDict()
-        self.yaml_loader = CTRexYAMLLoader("rpc_exceptions.yaml")
+        self.streams_list = {OrderedDict()}
+        self.yaml_loader = CTRexYAMLLoader("rpc_defaults.yaml")
         self._stream_id = 0
         # self._stream_by_name = {}
 
@@ -62,184 +63,155 @@ class CStreamList(object):
             new_stream_obj.load_data(**new_stream_data)
             self.append_stream(stream_name, new_stream_obj)
 
-
-
-        # start validating and reassembling clients input
-
+    def compile_streams(self):
+        stream_ids = {}
 
         pass
 
-class CRxStats(object):
-
-    def __init__(self, enabled=False, seq_enabled=False, latency_enabled=False):
-        self._rx_dict = {"enabled": enabled,
-                         "seq_enabled": seq_enabled,
-                         "latency_enabled": latency_enabled}
-
-    @property
-    def enabled(self):
-        return self._rx_dict.get("enabled")
 
-    @enabled.setter
-    def enabled(self, bool_value):
-        self._rx_dict['enabled'] = bool(bool_value)
+class CRxStats(object):
 
-    @property
-    def seq_enabled(self):
-        return self._rx_dict.get("seq_enabled")
+    FIELDS = ["seq_enabled", "latency_enabled"]
+    def __init__(self, enabled=False, **kwargs):
+        self.enabled = bool(enabled)
+        for field in CRxStats.FIELDS:
+            setattr(self, field, kwargs.get(field, False))
 
-    @seq_enabled.setter
-    def seq_enabled(self, bool_value):
-        self._rx_dict['seq_enabled'] = bool(bool_value)
+    def dump(self):
+        if self.enabled:
+            dump = {"enabled": True}
+            dump.update({k: getattr(self, k)
+                         for k in CRxStats.FIELDS
+                         if getattr(self, k)
+                         })
+            return dump
+        else:
+            return {"enabled": False}
 
-    @property
-    def latency_enabled(self):
-        return self._rx_dict.get("latency_enabled")
 
-    @latency_enabled.setter
-    def latency_enabled(self, bool_value):
-        self._rx_dict['latency_enabled'] = bool(bool_value)
-
-    def dump(self):
-        return {k: v
-                for k, v in self._rx_dict.items()
-                if v
-                }
 
 class CTxMode(object):
     """docstring for CTxMode"""
-    def __init__(self, tx_mode, pps):
-        super(CTxMode, self).__init__()
-        if tx_mode not in ["continuous", "single_burst", "multi_burst"]:
-            raise ValueError("Unknown TX mode ('{0}')has been initialized.".format(tx_mode))
-        self._tx_mode = tx_mode
-        self._fields = {'pps': float(pps)}
-        if tx_mode == "single_burst":
-            self._fields['total_pkts'] = 0
-        elif tx_mode == "multi_burst":
-            self._fields['pkts_per_burst'] = 0
-            self._fields['ibg'] = 0.0
-            self._fields['count'] = 0
-        else:
-            pass
+    GENERAL_FIELDS = ["type", "pps"]
+    FIELDS = {"continuous": [],
+              "single_burst": ["total_pkts"],
+              "multi_burst": ["pkts_per_burst", "ibg", "count"]}
+
+    def __init__(self, type, pps=0, **kwargs):
+        self._MODES = CTxMode.FIELDS.keys()
+        self.type = type
+        self.pps = pps
+        for field in CTxMode.FIELDS.get(self.type):
+            setattr(self, field, kwargs.get(field, 0))
 
-    def set_tx_mode_attr(self, attr, val):
-        if attr in self._fields:
-            self._fields[attr] = type(self._fields.get(attr))(val)
-        else:
-            raise ValueError("The provided attribute ('{0}') is not a legal attribute in selected TX mode ('{1}')".
-                             format(attr, self._tx_mode))
+    @property
+    def type(self):
+        return self._type
+
+    @type.setter
+    def type(self, type):
+        if type not in self._MODES:
+            raise ValueError("Unknown TX mode ('{0}')has been initialized.".format(type))
+        self._type = type
+        self._reset_fields()
 
     def dump(self):
-        dump = {"type": self._tx_mode}
-        dump.update({k: v
-                     for k, v in self._fields.items()
+        dump = ({k: getattr(self, k)
+                 for k in CTxMode.GENERAL_FIELDS
+                 })
+        dump.update({k: getattr(self, k)
+                     for k in CTxMode.FIELDS.get(self.type)
                      })
         return dump
 
+    def _reset_fields(self):
+        for field in CTxMode.FIELDS.get(self.type):
+            setattr(self, field, 0)
+
+
 class CStream(object):
     """docstring for CStream"""
-    DEFAULTS = {"rx_stats": CRxStats,
-                "mode": CTxMode,
-                "isg": 5.0,
-                "next_stream": -1,
-                "self_start": True,
-                "enabled": True}
 
     FIELDS = ["enabled", "self_start", "next_stream", "isg", "mode", "rx_stats", "packet", "vm"]
 
     def __init__(self):
-        super(CStream, self).__init__()
+        self.is_loaded = False
         for field in CStream.FIELDS:
             setattr(self, field, None)
 
     def load_data(self, **kwargs):
-        for k, v in kwargs.items():
-            if k == "rx_stats":
-                if isinstance(v, dict):
-                    setattr(self, k, CRxStats(**v))
-                elif isinstance(v, CRxStats):
-                    setattr(self, k, v)
-            elif k == "mode":
-                if isinstance(v, dict):
-                    setattr(self, k, CTxMode(v))
-                elif isinstance(v, CTxMode):
-                    setattr(self, k, v)
-            else:
-                setattr(self, k, v)
-
-
-
-    # def __init__(self, enabled, self_start, next_stream, isg, mode, rx_stats, packet, vm):
-    #     super(CStream, self).__init__()
-    #     for k, v in kwargs.items():
-    #         if k == "rx_stats":
-    #             if isinstance(v, dict):
-    #                 setattr(self, k, CRxStats(v))
-    #             elif isinstance(v, CRxStats):
-    #                 setattr(self, k, v)
-    #         elif k == "mode":
-    #             if isinstance(v, dict):
-    #                 setattr(self, k, CTxMode(v))
-    #             elif isinstance(v, CTxMode):
-    #                 setattr(self, k, v)
-    #         else:
-    #             setattr(self, k, v)
-    #     # set default values to unset attributes, according to DEFAULTS dict
-    #     set_keys = set(kwargs.keys())
-    #     keys_to_set = [x
-    #                    for x in self.DEFAULTS
-    #                    if x not in set_keys]
-    #     for key in keys_to_set:
-    #         default = self.DEFAULTS.get(key)
-    #         if type(default) == type:
-    #             setattr(self, key, default())
-    #         else:
-    #             setattr(self, key, default)
-
-    # @property
-    # def packet(self):
-    #     return self._packet
-    #
-    # @packet.setter
-    # def packet(self, packet_obj):
-    #     assert isinstance(packet_obj, CTRexPktBuilder)
-    #     self._packet = packet_obj
-    #
-    # @property
-    # def enabled(self):
-    #     return self._enabled
-    #
-    # @enabled.setter
-    # def enabled(self, bool_value):
-    #     self._enabled = bool(bool_value)
-    #
-    # @property
-    # def self_start(self):
-    #     return self._self_start
-    #
-    # @self_start.setter
-    # def self_start(self, bool_value):
-    #     self._self_start = bool(bool_value)
-    #
-    # @property
-    # def next_stream(self):
-    #     return self._next_stream
-    #
-    # @next_stream.setter
-    # def next_stream(self, value):
-    #     self._next_stream = int(value)
+        try:
+            for k in CStream.FIELDS:
+                if k == "rx_stats":
+                    rx_stats_data = kwargs[k]
+                    if isinstance(rx_stats_data, dict):
+                        setattr(self, k, CRxStats(**rx_stats_data))
+                    elif isinstance(rx_stats_data, CRxStats):
+                        setattr(self, k, rx_stats_data)
+                elif k == "mode":
+                    tx_mode = kwargs[k]
+                    if isinstance(tx_mode, dict):
+                        setattr(self, k, CTxMode(**tx_mode))
+                    elif isinstance(tx_mode, CTxMode):
+                        setattr(self, k, tx_mode)
+                elif k == "packet":
+                    if isinstance(kwargs[k], CTRexPktBuilder):
+                        if "vm" not in kwargs:
+                            self.load_packet_obj(kwargs[k])
+                        else:
+                            raise ValueError("When providing packet object with a CTRexPktBuilder, vm parameter "
+                                             "should not be supplied")
+                    else:
+                        binary = kwargs[k]["binary"]
+                        if isinstance(binary, list):
+                            setattr(self, k, kwargs[k])
+                        elif isinstance(binary, str) and binary.endswith(".pcap"):
+                            self.load_packet_from_pcap(binary, kwargs[k]["meta"])
+                        else:
+                            raise ValueError("Packet binary attribute has been loaded with unsupported value."
+                                             "Supported values are reference to pcap file with SINGLE packet, "
+                                             "or a list of unsigned-byte integers")
+                else:
+                    setattr(self, k, kwargs[k])
+            self.is_loaded = True
+        except KeyError as e:
+            cause = e.args[0]
+            raise KeyError("The attribute '{0}' is missing as a field of the CStream object.\n"
+                           "Loaded data must contain all of the following fields: {1}".format(cause, CStream.FIELDS))
+
+    def load_packet_obj(self, packet_obj):
+        assert isinstance(packet_obj, CTRexPktBuilder)
+        self.packet = packet_obj.dump_pkt()
+        self.vm = packet_obj.get_vm_data()
+
+    def load_packet_from_pcap(self, pcap_path, metadata=''):
+        with open(pcap_path, 'r') as f:
+            pcap = dpkt.pcap.Reader(f)
+            first_packet = True
+            for _, buf in pcap:
+                # this is an iterator, can't evaluate the number of files in advance
+                if first_packet:
+                    self.packet = {"binary": [struct.unpack('B', buf[i:i+1])[0] # represent data as list of 0-255 ints
+                                              for i in range(0, len(buf))],
+                                   "meta": metadata}    # meta data continues without a change.
+                    first_packet = False
+                else:
+                    raise ValueError("Provided pcap file contains more than single packet.")
+        # arrive here ONLY if pcap contained SINGLE packet
+        return
+
 
     def dump(self):
-        pass
-        return {"enabled": self.enabled,
-                "self_start": self.self_start,
-                "isg": self.isg,
-                "next_stream": self.next_stream,
-                "packet": self.packet.dump_pkt(),
-                "mode": self.mode.dump(),
-                "vm": self.packet.get_vm_data(),
-                "rx_stats": self.rx_stats.dump()}
+        if self.is_loaded:
+            dump = {}
+            for key in CStream.FIELDS:
+                try:
+                    dump[key] = getattr(self, key).dump()  # use dump() method of compound object, such TxMode
+                except AttributeError:
+                    dump[key] = getattr(self, key)
+            return dump
+        else:
+            raise RuntimeError("CStream object isn't loaded with data. Use 'load_data' method.")
 
 
 
-- 
cgit 


From d09df99769f67819c64a7a025dbdcd39811c7b44 Mon Sep 17 00:00:00 2001
From: Dan Klein <danklei@cisco.com>
Date: Tue, 20 Oct 2015 03:17:08 +0300
Subject: Major progress in console, yaml utils, and trex_streams basically
 done, minor changes remianing BIG ISSUE LEFT: rewire console to work with
 trexstateless client module

---
 .../trex_control_plane/common/trex_streams.py      | 85 ++++++++++++++--------
 1 file changed, 56 insertions(+), 29 deletions(-)

(limited to 'scripts/automation/trex_control_plane/common/trex_streams.py')

diff --git a/scripts/automation/trex_control_plane/common/trex_streams.py b/scripts/automation/trex_control_plane/common/trex_streams.py
index e366001d..674a6bcc 100755
--- a/scripts/automation/trex_control_plane/common/trex_streams.py
+++ b/scripts/automation/trex_control_plane/common/trex_streams.py
@@ -2,19 +2,21 @@
 
 import external_packages
 from client_utils.packet_builder import CTRexPktBuilder
-from collections import OrderedDict
+from collections import OrderedDict, namedtuple
 from client_utils.yaml_utils import *
 import dpkt
 import struct
+import copy
+import os
 
+StreamPack = namedtuple('StreamPack', ['stream_id', 'stream'])
 
 class CStreamList(object):
 
     def __init__(self):
-        self.streams_list = {OrderedDict()}
-        self.yaml_loader = CTRexYAMLLoader("rpc_defaults.yaml")
-        self._stream_id = 0
-        # self._stream_by_name = {}
+        self.streams_list = {}
+        self.yaml_loader = CTRexYAMLLoader(os.path.join(os.path.dirname(os.path.realpath(__file__)), 
+                                                        "rpc_defaults.yaml"))
 
     def append_stream(self, name, stream_obj):
         assert isinstance(stream_obj, CStream)
@@ -24,21 +26,19 @@ class CStreamList(object):
         return
 
     def remove_stream(self, name):
-        return self.streams_list.pop(name)
-
-    def rearrange_streams(self, streams_names_list, new_streams_dict={}):
-        tmp_list = OrderedDict()
-        for stream in streams_names_list:
-            if stream in self.streams_list:
-                tmp_list[stream] = self.streams_list.get(stream)
-            elif stream in new_streams_dict:
-                new_stream_obj = new_streams_dict.get(stream)
-                assert isinstance(new_stream_obj, CStream)
-                tmp_list[stream] = new_stream_obj
-            else:
-                raise NameError("Given stream named '{0}' cannot be found in existing stream list or and wasn't"
-                                "provided with the new_stream_dict parameter.".format(stream))
-        self.streams_list = tmp_list
+        popped = self.streams_list.pop(name)
+        if popped:
+            for stream_name, stream in self.streams_list.items():
+                if stream.next_stream_id == name:
+                    stream.next_stream_id = -1
+                try:
+                    rx_stats_stream = getattr(stream.rx_stats, "stream_id")
+                    if rx_stats_stream == name:
+                        # if a referenced stream of rx_stats object deleted, revert to rx stats of current stream 
+                        setattr(stream.rx_stats, "stream_id", stream_name)
+                except AttributeError as e:
+                    continue    # 
+        return popped
 
     def export_to_yaml(self, file_path):
         raise NotImplementedError("export_to_yaml method is not implemented, yet")
@@ -48,7 +48,6 @@ class CStreamList(object):
         self.streams_list.clear()
         streams_data = load_yaml_to_obj(file_path)
         assert isinstance(streams_data, list)
-        raw_streams = {}
         for stream in streams_data:
             stream_name = stream.get("name")
             raw_stream = stream.get("stream")
@@ -62,16 +61,41 @@ class CStreamList(object):
             new_stream_obj = CStream()
             new_stream_obj.load_data(**new_stream_data)
             self.append_stream(stream_name, new_stream_obj)
+        return streams_data
 
     def compile_streams(self):
+        # first, assign an id to each stream
         stream_ids = {}
-
-        pass
+        for idx, stream_name in enumerate(self.streams_list):
+            stream_ids[stream_name] = idx
+        # next, iterate over the streams and transform them from working with names to ids.
+        # with that build a new dict with old stream_name as the key, and StreamPack as the stored value 
+        compiled_streams = {}
+        for stream_name, stream in self.streams_list.items():
+            tmp_stream = CStreamList._compile_single_stream(stream_name, stream, stream_ids)
+            compiled_streams[stream_name] = StreamPack(stream_ids.get(stream_name),
+                                                       tmp_stream)
+        return compiled_streams
+
+    @staticmethod
+    def _compile_single_stream(stream_name, stream, id_dict):
+        # copy the old stream to temporary one, no change to class attributes
+        tmp_stream = copy.copy(stream)
+        next_stream_id = id_dict.get(getattr(tmp_stream, "next_stream_id"), -1)
+        try:
+            rx_stats_stream_id = id_dict.get(getattr(tmp_stream.rx_stats, "stream_id"),
+                                             id_dict.get(stream_name))
+        except AttributeError as e:
+            rx_stats_stream_id = id_dict.get(stream_name)
+        # assign resolved values to stream object
+        tmp_stream.next_stream_id = next_stream_id
+        tmp_stream.rx_stats.stream_id = rx_stats_stream_id
+        return tmp_stream
 
 
 class CRxStats(object):
 
-    FIELDS = ["seq_enabled", "latency_enabled"]
+    FIELDS = ["seq_enabled", "latency_enabled", "stream_id"]
     def __init__(self, enabled=False, **kwargs):
         self.enabled = bool(enabled)
         for field in CRxStats.FIELDS:
@@ -82,7 +106,7 @@ class CRxStats(object):
             dump = {"enabled": True}
             dump.update({k: getattr(self, k)
                          for k in CRxStats.FIELDS
-                         if getattr(self, k)
+                         if getattr(self, k) or k == "stream_id"
                          })
             return dump
         else:
@@ -132,10 +156,12 @@ class CTxMode(object):
 class CStream(object):
     """docstring for CStream"""
 
-    FIELDS = ["enabled", "self_start", "next_stream", "isg", "mode", "rx_stats", "packet", "vm"]
+    FIELDS = ["enabled", "self_start", "next_stream_id", "isg", "mode", "rx_stats", "packet", "vm"]
+    # COMPILE_FIELDS = ["enabled", "self_start", "next_stream_id", "isg", "mode", "rx_stats", "packet", "vm"]
 
     def __init__(self):
         self.is_loaded = False
+        self._is_compiled = False
         for field in CStream.FIELDS:
             setattr(self, field, None)
 
@@ -201,7 +227,8 @@ class CStream(object):
         return
 
 
-    def dump(self):
+    def dump(self, compilation=False):
+        # fields = CStream.COMPILE_FIELDS if compilation else CStream.FIELDS
         if self.is_loaded:
             dump = {}
             for key in CStream.FIELDS:
@@ -213,8 +240,8 @@ class CStream(object):
         else:
             raise RuntimeError("CStream object isn't loaded with data. Use 'load_data' method.")
 
-
-
+    def dump_compiled(self):
+        return self.dump(compilation=True)
 
 
 
-- 
cgit 


From 5abe21ffb26a15c2a63e90b5628d704e8211b599 Mon Sep 17 00:00:00 2001
From: Dan Klein <danklei@cisco.com>
Date: Tue, 20 Oct 2015 09:12:33 +0300
Subject: + Added traffic options at stl directory + updated console to support
 multiplier on loading + fixed minor issues at yaml_utils and trex_streams
 objects + console not stable, YET

---
 scripts/automation/trex_control_plane/common/trex_streams.py | 6 +++---
 1 file changed, 3 insertions(+), 3 deletions(-)

(limited to 'scripts/automation/trex_control_plane/common/trex_streams.py')

diff --git a/scripts/automation/trex_control_plane/common/trex_streams.py b/scripts/automation/trex_control_plane/common/trex_streams.py
index 1aeb46b0..783f2769 100755
--- a/scripts/automation/trex_control_plane/common/trex_streams.py
+++ b/scripts/automation/trex_control_plane/common/trex_streams.py
@@ -43,7 +43,7 @@ class CStreamList(object):
     def export_to_yaml(self, file_path):
         raise NotImplementedError("export_to_yaml method is not implemented, yet")
 
-    def load_yaml(self, file_path, multiplier_dict={}):
+    def load_yaml(self, file_path, multiplier=1):
         # clear all existing streams linked to this object
         self.streams_list.clear()
         streams_data = load_yaml_to_obj(file_path)
@@ -57,11 +57,11 @@ class CStreamList(object):
                                  "Provided item was:\n {stream}".format(stream))
             new_stream_data = self.yaml_loader.validate_yaml(raw_stream,
                                                              "stream",
-                                                             multiplier= multiplier_dict.get(stream_name, 1))
+                                                             multiplier= multiplier)
             new_stream_obj = CStream()
             new_stream_obj.load_data(**new_stream_data)
             self.append_stream(stream_name, new_stream_obj)
-        return streams_data
+        return new_stream_data
 
     def compile_streams(self):
         # first, assign an id to each stream
-- 
cgit