summaryrefslogtreecommitdiffstats
path: root/scripts/automation/trex_control_plane/common
diff options
context:
space:
mode:
authorDan Klein <danklein10@gmail.com>2015-10-15 09:57:35 +0300
committerDan Klein <danklein10@gmail.com>2015-10-15 09:57:35 +0300
commit0c5a4348a31e0e8d76dd1fcf378cb2c0a2867f59 (patch)
treedcaa9ab3c33b0e62aa41e29e6a6429194a956b71 /scripts/automation/trex_control_plane/common
parent2dd1a4d85c559ddafe695b6d6d393ee086e1a3de (diff)
updated yaml utils and stream object
Diffstat (limited to 'scripts/automation/trex_control_plane/common')
-rwxr-xr-xscripts/automation/trex_control_plane/common/external_packages.py28
-rw-r--r--scripts/automation/trex_control_plane/common/rpc_defaults.yaml107
-rw-r--r--scripts/automation/trex_control_plane/common/trex_status.py8
-rw-r--r--scripts/automation/trex_control_plane/common/trex_streams.py190
4 files changed, 333 insertions, 0 deletions
diff --git a/scripts/automation/trex_control_plane/common/external_packages.py b/scripts/automation/trex_control_plane/common/external_packages.py
new file mode 100755
index 00000000..62121d4f
--- /dev/null
+++ b/scripts/automation/trex_control_plane/common/external_packages.py
@@ -0,0 +1,28 @@
+#!/router/bin/python
+
+import sys
+import os
+
+CURRENT_PATH = os.path.dirname(os.path.realpath(__file__))
+ROOT_PATH = os.path.abspath(os.path.join(CURRENT_PATH, os.pardir)) # path to trex_control_plane directory
+PATH_TO_PYTHON_LIB = os.path.abspath(os.path.join(ROOT_PATH, os.pardir, os.pardir, 'external_libs'))
+
+CLIENT_UTILS_MODULES = ['PyYAML-3.01/lib'
+ ]
+
+def import_common_modules():
+ # must be in a higher priority
+ sys.path.insert(0, PATH_TO_PYTHON_LIB)
+ sys.path.append(ROOT_PATH)
+ import_module_list(CLIENT_UTILS_MODULES)
+
+
+def import_module_list(modules_list):
+ assert(isinstance(modules_list, list))
+ for p in modules_list:
+ full_path = os.path.join(PATH_TO_PYTHON_LIB, p)
+ fix_path = os.path.normcase(full_path)
+ sys.path.insert(1, full_path)
+
+import_common_modules()
+
diff --git a/scripts/automation/trex_control_plane/common/rpc_defaults.yaml b/scripts/automation/trex_control_plane/common/rpc_defaults.yaml
new file mode 100644
index 00000000..fbaca40e
--- /dev/null
+++ b/scripts/automation/trex_control_plane/common/rpc_defaults.yaml
@@ -0,0 +1,107 @@
+##############################################################
+#### TRex RPC stream list default values ####
+##############################################################
+
+# this document is based on TRex RPC server spec and its fields:
+# http://trex-tgn.cisco.com/trex/doc/trex_rpc_server_spec.html
+
+### HOW TO READ THIS FILE
+# 1. Each key represents an object type
+# 2. Each value can be either a value field or another object
+# 2.1. If a value field, read as:
+# + type: type of field
+# + has_default: if the value has any default
+# + default: the default value (Only appears if has_default field is 'YES')
+# 2.2. If an object type, jump to correspoding object key.
+# 3. If an object has more than one instance type, another layer with the type shall be added.
+# For example, 'mode' object has 3 types: 'continuous', 'single_burst', 'multi_burst'
+# So, 3 mode objects will be defined, named:
+# - mode['continuous']
+# - mode['single_burst']
+# - mode['multi_burst']
+# In this case, there's no default for the 'type' field on the object
+# 4. Some values has 'multiplier' property attached.
+# In such case, the loaded value will be multiplied by the multiplier
+# For example, if the mode's 'pps' field value is 10, and its multiplier is 5,
+# the loaded pps value will be 10*5=50
+
+
+stream:
+ enabled:
+ type: boolean
+ has_default: YES
+ default: True
+ self_start:
+ type: boolean
+ has_default: YES
+ default: True
+ isg:
+ type: double
+ has_default: YES
+ default: 0.0
+ next_stream_id:
+ type: [int, string] # string to allow naming binding
+ has_default: YES
+ default: -1 # no next streams
+ packet:
+ type: object
+ mode:
+ type: object
+ vm:
+ type: array
+ has_default: YES
+ default: [] # no ranging instructions
+ rx_stats:
+ type: object
+
+packet:
+ binary:
+ type: [array,string]
+ has_default: NO
+ meta:
+ type: string
+ has_default: YES
+ default: ""
+
+mode:
+ continuous:
+ pps:
+ type: double
+ has_default: NO
+ multiplier: 1.0
+ single_burst:
+ pps:
+ type: int
+ has_default: NO
+ total_pkts:
+ type: int
+ has_default: NO
+ multiplier: 1.0
+ multi_burst:
+ pps:
+ type: int
+ has_default: NO
+ pkts_per_burst:
+ type: int
+ has_default: NO
+ ibg:
+ type: double
+ has_default: YES
+ default: 100.0
+ count:
+ type: int
+ has_default: YES
+ default: 0 # loop forever
+ multiplier: 1.0
+
+rx_stats:
+ enabled:
+ type: boolean
+ has_default: YES
+ default: False
+ seq_enabled:
+ type: boolean
+ has_default: NO
+ latency_enabled:
+ type: boolean
+ has_default: NO \ No newline at end of file
diff --git a/scripts/automation/trex_control_plane/common/trex_status.py b/scripts/automation/trex_control_plane/common/trex_status.py
new file mode 100644
index 00000000..f132720c
--- /dev/null
+++ b/scripts/automation/trex_control_plane/common/trex_status.py
@@ -0,0 +1,8 @@
+#!/router/bin/python
+
+# define the states in which a T-Rex can hold during its lifetime
+# TRexStatus = Enum('TRexStatus', 'Idle Starting Running')
+
+IDLE = 1
+STARTING = 2
+RUNNING = 3
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