diff options
Diffstat (limited to 'scripts')
3 files changed, 154 insertions, 193 deletions
diff --git a/scripts/automation/trex_control_plane/client_utils/yaml_utils.py b/scripts/automation/trex_control_plane/client_utils/yaml_utils.py index 3ec3c9c8..0d808880 100755 --- a/scripts/automation/trex_control_plane/client_utils/yaml_utils.py +++ b/scripts/automation/trex_control_plane/client_utils/yaml_utils.py @@ -30,14 +30,6 @@ class CTRexYAMLLoader(object): self.yaml_path = yaml_ref_file_path self.ref_obj = None - def load_reference(self): - try: - self.ref_obj = yaml.load(file(self.yaml_path, 'r')) - except yaml.YAMLError as e: - raise - except Exception as e: - raise - def check_term_param_type(self, val, val_field, ref_val, multiplier): print val, val_field, ref_val tmp_type = ref_val.get('type') @@ -85,7 +77,7 @@ class CTRexYAMLLoader(object): if isinstance(evaluated_obj, dict) and evaluated_obj.keys() == [root_obj]: evaluated_obj = evaluated_obj.get(root_obj) if not self.ref_obj: - self.load_reference() + self.ref_obj = load_yaml_to_obj(self.yaml_path) # load reference object to class attribute. ref_item = self.ref_obj.get(root_obj) if ref_item is not None: try: @@ -151,104 +143,13 @@ class CTRexYAMLLoader(object): return val - - - - -# -# def yaml_obj_validator(evaluated_obj, yaml_reference_file_path, root_obj, fill_defaults=True): -# """ -# validate SINGLE ROOT object with yaml reference file. -# Fills up default values if hasn't been assigned by user and available. -# -# :param evaluated_obj: python object that should match the yaml reference file -# :param yaml_reference_file_path: -# :param fill_defaults: -# :return: a python representation object of the YAML file if OK -# """ -# type_dict = {"double":float, -# "int":int, -# "array":list, -# "string":str, -# "boolean":bool} -# -# def validator_rec_helper(obj_to_eval, ref_obj, root_key): -# ref_item = ref_obj.get(root_key) -# if ref_item is not None: -# if "type" in obj_to_eval: -# ref_item = ref_item[obj_to_eval.get("type")] -# if isinstance(ref_item, dict) and "type" not in ref_item: # this is not a terminal -# result_obj = {} -# # iterate over key-value pairs -# for k, v in ref_item.items(): -# if k in obj_to_eval: -# # need to validate with ref obj -# tmp_type = v.get('type') -# if tmp_type == "object": -# # go deeper into nesting hierarchy -# result_obj[k] = validator_rec_helper(obj_to_eval.get(k), ref_obj, k) -# elif isinstance(tmp_type, list): -# # item can be one of multiple types -# python_types = set() -# for t in tmp_type: -# if t in type_dict: -# python_types.add(type_dict.get(t)) -# else: -# raise TypeError("Unknown resolving for type {0}".format(t)) -# if type(obj_to_eval[k]) not in python_types: -# raise TypeError("Type of object field '{0}' is not allowed".format(k)) -# -# else: -# # this is a single type field -# python_type = type_dict.get(tmp_type) -# if not isinstance(obj_to_eval[k], python_type): -# raise TypeError("Type of object field '{0}' is not allowed".format(k)) -# else: -# # WE'RE OK! -# result_obj[k] = obj_to_eval[k] -# else: -# # this is an object field that wasn't specified by the user -# if v.get('has_default'): -# # WE'RE OK! -# result_obj[k] = v.get('default') -# else: -# # This is a mandatory field! -# raise ValueError("The {0} field is mandatory and must be specified explicitly".format(v)) -# return result_obj -# -# elif isinstance(ref_item, list): -# return [] -# else: -# -# -# -# else: -# raise KeyError("The given key is not ") -# -# -# -# -# pass -# pass -# elif isinstance(obj_to_eval, list): -# # iterate as list sequence -# pass -# else: -# # evaluate as single item -# pass -# pass -# -# try: -# yaml_ref = yaml.load(file(yaml_reference_file_path, 'r')) -# result = validator_rec_helper(evaluated_obj, yaml_ref, root_obj) -# -# except yaml.YAMLError as e: -# raise -# except Exception: -# raise - -def yaml_loader(file_path): - pass +def load_yaml_to_obj(file_path): + try: + return yaml.load(file(file_path, 'r')) + except yaml.YAMLError as e: + raise + except Exception as e: + raise def yaml_exporter(file_path): pass diff --git a/scripts/automation/trex_control_plane/common/rpc_defaults.yaml b/scripts/automation/trex_control_plane/common/rpc_defaults.yaml index 576710a3..5816f980 100755 --- a/scripts/automation/trex_control_plane/common/rpc_defaults.yaml +++ b/scripts/automation/trex_control_plane/common/rpc_defaults.yaml @@ -41,7 +41,7 @@ stream: type: [int, double, string]
has_default: YES
default: 0.0
- next_stream_id:
+ next_stream:
type: [int, string] # string to allow naming binding
has_default: YES
default: -1 # no next streams
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 |