From f6d11f9e01e39fe2688558c7598f22ce9feb35da Mon Sep 17 00:00:00 2001 From: imarom Date: Sun, 25 Sep 2016 18:45:04 +0300 Subject: merge issues with rand limit --- .../stl/trex_stl_lib/trex_stl_exceptions.py | 25 +++++---- .../stl/trex_stl_lib/trex_stl_sim.py | 7 --- src/rpc-server/commands/trex_rpc_cmd_stream.cpp | 12 ++++- src/stateless/cp/trex_stream_vm.cpp | 60 ++++++++++------------ src/stateless/cp/trex_stream_vm.h | 60 +++++++++------------- 5 files changed, 73 insertions(+), 91 deletions(-) diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_exceptions.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_exceptions.py index b6fad865..2ca92cb8 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_exceptions.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_exceptions.py @@ -1,6 +1,6 @@ import os import sys -import linecache +import traceback from .utils.text_opts import * @@ -13,23 +13,19 @@ except NameError: class STLError(Exception): def __init__ (self, msg): self.msg = str(msg) + self.tb = traceback.extract_stack() def __str__ (self): - exc_type, exc_obj, exc_tb = sys.exc_info() - if not exc_tb: - return self.msg - fname = os.path.split(exc_tb.tb_frame.f_code.co_filename)[1] - - - src_line = str(linecache.getline(fname, exc_tb.tb_lineno)) + fname = os.path.split(self.tb[-2][0])[1] + lineno = self.tb[-2][1] + func = self.tb[-2][2] + src = self.tb[-2][3] s = "\n******\n" - s += "Error at {0}:{1} - '{2}'\n\n".format(format_text(fname, 'bold'), format_text(exc_tb.tb_lineno, 'bold'), format_text(src_line.strip(), 'bold')) + s += "Error at {0}:{1} - '{2}'\n\n".format(format_text(fname, 'bold'), format_text(lineno, 'bold'), format_text(src.strip(), 'bold')) s += "specific error:\n\n{0}\n".format(format_text(self.msg, 'bold')) - - return s def brief (self): @@ -40,17 +36,18 @@ class STLError(Exception): class STLStateError(STLError): def __init__ (self, op, state): self.msg = "Operation '{0}' is not valid while '{1}'".format(op, state) - + self.tb = traceback.extract_stack() # port state error class STLPortStateError(STLError): def __init__ (self, port, op, state): self.msg = "Operation '{0}' on port(s) '{1}' is not valid while port(s) '{2}'".format(op, port, state) - + self.tb = traceback.extract_stack() # raised when argument value is not valid for operation class STLArgumentError(STLError): def __init__ (self, name, got, valid_values = None, extended = None): + self.tb = traceback.extract_stack() self.msg = "Argument: '{0}' invalid value: '{1}'".format(name, got) if valid_values: self.msg += " - valid values are '{0}'".format(valid_values) @@ -61,12 +58,14 @@ class STLArgumentError(STLError): # raised when argument type is not valid for operation class STLTypeError(STLError): def __init__ (self, arg_name, arg_type, valid_types): + self.tb = traceback.extract_stack() self.msg = "Argument: '%s' invalid type: '%s', expecting type(s): %s." % (arg_name, arg_type.__name__, [t.__name__ for t in valid_types] if isinstance(valid_types, tuple) else valid_types.__name__) # raised when timeout occurs class STLTimeoutError(STLError): def __init__ (self, timeout): + self.tb = traceback.extract_stack() self.msg = "Timeout: operation took more than '{0}' seconds".format(timeout) diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_sim.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_sim.py index 54ec2da9..540bba68 100644 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_sim.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_sim.py @@ -520,9 +520,6 @@ def compare_caps_strict (cap1, cap2, max_diff_sec = (5 * 1e-6)): if pkt1[0] != pkt2[0]: print(format_text("RAW error: cap files '{0}', '{1}' differ in cap #{2}\n".format(cap1, cap2, i), 'bold')) - - #d1 = hexdump(pkt1[0]) - #d2 = hexdump(pkt2[0]) diff_list = hexdiff(pkt1[0], pkt2[0]) @@ -532,10 +529,6 @@ def compare_caps_strict (cap1, cap2, max_diff_sec = (5 * 1e-6)): print("\n{0} - packet #{1}:\n".format(cap2, i)) prettyhex(pkt2[0], diff_list) - #print(hexdump(pkt1[0])) - #print("") - #print(hexdump(pkt2[0])) - #print("") print("") return False diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp index 3afa2457..bf48931a 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp @@ -312,6 +312,10 @@ TrexRpcCmdAddStream::check_min_max(uint8_t flow_var_size, uint64_t max_value, Json::Value &result){ + if (step == 0) { + generate_parse_err(result, "VM: step cannot be 0"); + } + if (max_value < min_value ) { std::stringstream ss; ss << "VM: request flow var variable '" << max_value << "' is smaller than " << min_value; @@ -341,6 +345,7 @@ TrexRpcCmdAddStream::check_min_max(uint8_t flow_var_size, generate_parse_err(result, ss.str()); } } + } void @@ -360,11 +365,11 @@ TrexRpcCmdAddStream::parse_vm_instr_flow_var_rand_limit(const Json::Value &inst, generate_parse_err(result, ss.str()); } - check_min_max(flow_var_size, 0, 0, min_value, max_value, result); + check_min_max(flow_var_size, 0, 1, min_value, max_value, result); stream->m_vm.add_instruction(new StreamVmInstructionFlowRandLimit(flow_var_name, flow_var_size, - (int)limit, + limit, min_value, max_value, seed) @@ -400,6 +405,9 @@ TrexRpcCmdAddStream::parse_vm_instr_flow_var(const Json::Value &inst, std::uniqu check_min_max(flow_var_size, init_value, step, min_value, max_value, result); + /* implicit range padding if possible */ + handle_range_padding(max_value,min_value,step, op_type, result); + stream->m_vm.add_instruction(new StreamVmInstructionFlowMan(flow_var_name, flow_var_size, op_type, diff --git a/src/stateless/cp/trex_stream_vm.cpp b/src/stateless/cp/trex_stream_vm.cpp index 106b5ea3..c157ab06 100644 --- a/src/stateless/cp/trex_stream_vm.cpp +++ b/src/stateless/cp/trex_stream_vm.cpp @@ -133,30 +133,27 @@ void StreamVmInstructionFlowMan::sanity_check_valid_range(uint32_t ins_id,Stream -uint8_t StreamVmInstructionFlowMan::bss_init_value(uint8_t *p){ - uint8_t res; +uint8_t StreamVmInstructionFlowMan::set_bss_init_value(uint8_t *p) { + + uint64_t prev = peek_prev(); switch (m_size_bytes) { case 1: - *p=(uint8_t)get_bss_init_value(); - res=1; - break; + *p=(uint8_t)prev; + return 1; case 2: - *((uint16_t*)p)=(uint16_t)get_bss_init_value(); - res=2; - break; + *((uint16_t*)p)=(uint16_t)prev; + return 2; case 4: - *((uint32_t*)p)=(uint32_t)get_bss_init_value(); - res=4; - break; + *((uint32_t*)p)=(uint32_t)prev; + return 4; case 8: - *((uint64_t*)p)=(uint64_t)get_bss_init_value(); - res=8; - break; + *((uint64_t*)p)=(uint64_t)prev; + return 8; default: assert(0); + return(0); } - return(res); } @@ -179,7 +176,7 @@ void StreamVmInstructionFlowRandLimit::sanity_check(uint32_t ins_id,StreamVm *lp } -uint8_t StreamVmInstructionFlowRandLimit::bss_init_value(uint8_t *p){ +uint8_t StreamVmInstructionFlowRandLimit::set_bss_init_value(uint8_t *p){ uint8_t res; typedef union ua_ { @@ -305,26 +302,25 @@ void StreamVmInstructionFlowClient::Dump(FILE *fd){ } -uint8_t StreamVmInstructionFlowClient::bss_init_value(uint8_t *p){ +uint8_t StreamVmInstructionFlowClient::set_bss_init_value(uint8_t *p) { - if (m_client_min>0) { - *((uint32_t*)p)=(uint32_t)(m_client_min-1); - }else{ - *((uint32_t*)p)=(uint32_t)m_client_min; - } + uint32_t bss_ip; + uint16_t bss_port; - p+=4; + /* fetch the previous values by 1 */ + peek_prev(bss_ip, bss_port, 1); - if (is_unlimited_flows() ) { - *((uint16_t*)p)=StreamDPOpClientsUnLimit::CLIENT_UNLIMITED_MIN_PORT; - }else{ - *((uint16_t*)p)=(uint16_t)m_port_min; - } + /* ip */ + *((uint32_t*)p) = bss_ip; + p += 4; - p+=2; + /* port */ + *((uint16_t*)p) = bss_port; + p += 2; - *((uint32_t*)p)=0; - p+=4; + /* reserve */ + *((uint32_t*)p) = 0; + p += 4; return (get_flow_var_size()); } @@ -1057,7 +1053,7 @@ void StreamVm::build_bss() { } for (auto inst : m_inst_list) { - p+=inst->bss_init_value(p); + p+=inst->set_bss_init_value(p); } } diff --git a/src/stateless/cp/trex_stream_vm.h b/src/stateless/cp/trex_stream_vm.h index 92fefbb3..be0c03ba 100644 --- a/src/stateless/cp/trex_stream_vm.h +++ b/src/stateless/cp/trex_stream_vm.h @@ -912,11 +912,11 @@ public: bool is_var_instruction() const { instruction_type_t type = get_instruction_type(); - return ( (type == itFLOW_MAN) || (type == itFLOW_CLIENT) ); + return ( (type == itFLOW_MAN) || (type == itFLOW_CLIENT) || (type == itFLOW_RAND_LIMIT) ); } /* nothing to init */ - virtual uint8_t bss_init_value(uint8_t *p){ + virtual uint8_t set_bss_init_value(uint8_t *p) { return (0); } @@ -941,11 +941,6 @@ public: return m_var_name; } - /** - * what is the split range for this var - * - */ - //virtual uint64_t get_range() const = 0; /** * allows a var instruction to be updated @@ -1010,7 +1005,7 @@ public: } - virtual uint8_t bss_init_value(uint8_t *p); + virtual uint8_t set_bss_init_value(uint8_t *p); /** @@ -1022,17 +1017,6 @@ public: FLOW_VAR_OP_RANDOM }; - - /** - * for BSS we take one previous value - * because the VM will be executed before writing to pkt - * so the init value is one step's advanced - * - */ - uint64_t get_bss_init_value() const { - return peek_prev(); - } - StreamVmInstructionFlowMan(const std::string &var_name, uint8_t size, flow_var_op_e op, @@ -1121,7 +1105,7 @@ private: public: /* flow var size */ - uint8_t m_size_bytes; + uint8_t m_size_bytes; /* type of op */ flow_var_op_e m_op; @@ -1148,22 +1132,16 @@ public: return ( StreamVmInstruction::itFLOW_RAND_LIMIT); } - virtual bool is_valid_for_split() const { - return (false); - } - - - virtual uint64_t get_splitable_range() const { - return (1); + virtual bool need_split() const { + return true; } - StreamVmInstructionFlowRandLimit(const std::string &var_name, uint8_t size, uint64_t limit, uint64_t min_value, uint64_t max_value, - int seed + uint64_t seed ) : StreamVmInstructionVar(var_name) { m_size_bytes = size; @@ -1177,7 +1155,7 @@ public: void sanity_check(uint32_t ins_id,StreamVm *lp); - virtual uint8_t bss_init_value(uint8_t *p); + virtual uint8_t set_bss_init_value(uint8_t *p); virtual StreamVmInstruction * clone() { return new StreamVmInstructionFlowRandLimit(m_var_name, @@ -1188,6 +1166,19 @@ public: m_seed); } + virtual void update(uint64_t phase, uint64_t step_mul) { + + /* phase */ + m_seed = m_seed * ( ( (phase + 1) * 514229 ) & 0xFFFFFFFF ); + + /* limit */ + uint64_t per_core_limit = (m_limit / step_mul); + if (phase == 0) { + per_core_limit += (m_limit % step_mul); + } + m_limit = per_core_limit; + } + private: void sanity_check_valid_size(uint32_t ins_id,StreamVm *lp); @@ -1197,7 +1188,7 @@ public: uint64_t m_min_value; uint64_t m_max_value; - int m_seed; + uint64_t m_seed; uint8_t m_size_bytes; }; @@ -1332,7 +1323,7 @@ public: } - virtual uint8_t bss_init_value(uint8_t *p); + virtual uint8_t set_bss_init_value(uint8_t *p); bool is_unlimited_flows(){ @@ -1340,11 +1331,6 @@ public: StreamVmInstructionFlowClient::CLIENT_F_UNLIMITED_FLOWS ); } - void get_bss_init_value(uint32_t &ip, uint16_t &port) { - /* fetch the previous values by 1 */ - peek_prev(ip, port, 1); - } - virtual StreamVmInstruction * clone() { return new StreamVmInstructionFlowClient(*this); } -- cgit 1.2.3-korg