summaryrefslogtreecommitdiffstats
path: root/scripts/automation/trex_control_plane/stl
diff options
context:
space:
mode:
authorimarom <imarom@cisco.com>2016-02-08 09:01:11 -0500
committerimarom <imarom@cisco.com>2016-02-08 09:01:55 -0500
commitf5a5e50bfe046148a20f6ce578d6082119dec2c0 (patch)
tree10bd95aa2ae3fb831dad7102ccbd5bd372199f54 /scripts/automation/trex_control_plane/stl
parent5be5c499e145656daf748b0092732b1cb092e445 (diff)
stream ID allocation
Diffstat (limited to 'scripts/automation/trex_control_plane/stl')
-rw-r--r--scripts/automation/trex_control_plane/stl/rpc_defaults.yaml124
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_port.py37
-rw-r--r--scripts/automation/trex_control_plane/stl/trex_stl_streams.py46
3 files changed, 74 insertions, 133 deletions
diff --git a/scripts/automation/trex_control_plane/stl/rpc_defaults.yaml b/scripts/automation/trex_control_plane/stl/rpc_defaults.yaml
deleted file mode 100644
index ad814b3e..00000000
--- a/scripts/automation/trex_control_plane/stl/rpc_defaults.yaml
+++ /dev/null
@@ -1,124 +0,0 @@
-##############################################################
-#### 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 corresponding 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 'multiply' 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
-# 5. Any object type must be listed by the user, even if all its field are defaults.
-# The most basic option would be to declare the object with "[]", which stands for empty object in YAML syntax.
-
-
-stream:
- enabled:
- type: boolean
- has_default: YES
- default: True
- self_start:
- type: boolean
- has_default: YES
- default: True
- isg:
- type: [int, double, string]
- has_default: YES
- default: 0.0
- next_stream_id:
- type: string # string to allow naming binding
- has_default: YES
- default: -1 # no next streams
- packet:
- type: object
- mode:
- type: object
- vm:
- type: object
- rx_stats:
- type: object
-
-packet:
- binary:
- type: [array,string]
- has_default: NO
- meta:
- type: string
- has_default: YES
- default: ""
-
-mode:
- continuous:
- pps:
- type: [int, double]
- has_default: NO
- multiply: YES
- single_burst:
- pps:
- type: [int, double]
- has_default: NO
- multiply: YES
- total_pkts:
- type: int
- has_default: NO
- multi_burst:
- pps:
- type: [int, double]
- has_default: NO
- multiply: YES
- pkts_per_burst:
- type: int
- has_default: NO
- ibg:
- type: [int, double, string]
- has_default: YES
- default: 100.0
- count:
- type: int
- has_default: YES
- default: 0 # loop forever
-
-rx_stats:
- enabled:
- type: boolean
- has_default: YES
- default: False
- stream_id:
- type: string
- has_default: YES
- default: False # use related stream_id
- seq_enabled:
- type: boolean
- has_default: YES
- default: False
- latency_enabled:
- type: boolean
- has_default: YES
- default: False
-
-vm:
- instructions:
- type: array
- has_default: YES
- default: []
- split_by_var:
- type: string
- has_default: YES
- default: ""
-
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_port.py b/scripts/automation/trex_control_plane/stl/trex_stl_port.py
index 8923d3d6..b2cf1c90 100644
--- a/scripts/automation/trex_control_plane/stl/trex_stl_port.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_port.py
@@ -52,6 +52,8 @@ class Port(object):
self.port_stats = trex_stl_stats.CPortStats(self)
+ self.next_available_id = 1
+
def err(self, msg):
return RC_ERR("port {0} : {1}".format(self.port_id, msg))
@@ -130,6 +132,8 @@ class Port(object):
# TODO: handle syncing the streams into stream_db
+ self.next_available_id = rc.data()['max_stream_id']
+
return self.ok()
@@ -139,6 +143,12 @@ class Port(object):
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
def add_streams (self, streams_list):
@@ -148,8 +158,33 @@ class Port(object):
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]
+
+ lookup = {}
+
+ # allocate IDs
+ for stream in streams_list:
+ if stream.get_id() == None:
+ stream.set_id(self.__allocate_stream_id())
+
+ lookup[stream.get_name()] = stream.get_id()
+
+ # resolve names
+ for stream in streams_list:
+ next_id = -1
+
+ next = stream.get_next()
+ if next:
+ if not next in lookup:
+ return self.err("stream dependency error - unable to find '{0}'".format(next))
+ next_id = lookup[next]
+
+ stream.fields['next_stream_id'] = next_id
+
+
batch = []
- for stream in (streams_list if isinstance(streams_list, list) else [streams_list]):
+ for stream in streams_list:
params = {"handler": self.handler,
"port_id": self.port_id,
diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_streams.py b/scripts/automation/trex_control_plane/stl/trex_stl_streams.py
index d5cba9e2..798b2f67 100644
--- a/scripts/automation/trex_control_plane/stl/trex_stl_streams.py
+++ b/scripts/automation/trex_control_plane/stl/trex_stl_streams.py
@@ -11,6 +11,11 @@ from dpkt import pcap
import random
import yaml
import base64
+import string
+
+def random_name (l):
+ return ''.join(random.choice(string.ascii_uppercase + string.digits) for _ in range(l))
+
# base class for TX mode
class STLTXMode(object):
@@ -86,13 +91,14 @@ class STLTXMultiBurst(STLTXMode):
class STLStream(object):
def __init__ (self,
+ name = random_name(8),
packet = None,
mode = STLTXCont(1),
enabled = True,
self_start = True,
isg = 0.0,
rx_stats = None,
- next_stream_id = -1,
+ next = None,
stream_id = None):
# type checking
@@ -111,21 +117,21 @@ class STLStream(object):
if not isinstance(isg, (int, float)):
raise STLArgumentError('isg', isg)
- if (type(mode) == STLTXCont) and (next_stream_id != -1):
+ if (type(mode) == STLTXCont) and (next != None):
raise STLError("continuous stream cannot have a next stream ID")
- self.fields = {}
+ # tag for the stream and next - can be anything
+ self.name = name
+ self.next = next
+ self.set_id(stream_id)
- # use a random 31 bit for ID
- self.fields['stream_id'] = stream_id if stream_id is not None else random.getrandbits(31)
+ self.fields = {}
# basic fields
self.fields['enabled'] = enabled
self.fields['self_start'] = self_start
self.fields['isg'] = isg
- self.fields['next_stream_id'] = next_stream_id
-
# mode
self.fields['mode'] = mode.to_json()
@@ -153,8 +159,20 @@ class STLStream(object):
return self.fields
def get_id (self):
- return self.fields['stream_id']
+ return self.id
+
+ def set_id (self, id):
+ self.id = id
+
+ def get_name (self):
+ return self.name
+ def get_next (self):
+ return self.next
+
+
+ def to_yaml (self):
+ fields = dict(stream.fields)
@staticmethod
@@ -228,3 +246,15 @@ class STLStream(object):
return streams
+
+class STLYAMLLoader(object):
+ def __init__ (self, yaml_file):
+ self.yaml_file = yaml_file
+
+ def load (self):
+ with open(self.yaml_file, 'r') as f:
+ yaml_str = f.read()
+ objects = yaml.load(yaml_str)
+
+ for object in objects:
+ pass