merge issues with rand limit
authorimarom <[email protected]>
Sun, 25 Sep 2016 15:45:04 +0000 (18:45 +0300)
committerimarom <[email protected]>
Sun, 25 Sep 2016 15:45:04 +0000 (18:45 +0300)
scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_exceptions.py
scripts/automation/trex_control_plane/stl/trex_stl_lib/trex_stl_sim.py
src/rpc-server/commands/trex_rpc_cmd_stream.cpp
src/stateless/cp/trex_stream_vm.cpp
src/stateless/cp/trex_stream_vm.h

index b6fad86..2ca92cb 100644 (file)
@@ -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)
 
 
index 54ec2da..540bba6 100644 (file)
@@ -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
 
index 3afa245..bf48931 100644 (file)
@@ -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,
index 106b5ea..c157ab0 100644 (file)
@@ -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);
     }
 }
 
index 92fefbb..be0c03b 100644 (file)
@@ -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);
     }