From 2cf444195c3d8a0215216e5f1899fded15bd7627 Mon Sep 17 00:00:00 2001 From: imarom Date: Wed, 21 Sep 2016 18:12:46 +0300 Subject: [PATCH] Splitter - padding for non circular VMs --- .../regression/functional_tests/stl_basic_tests.py | 37 +++++++++++----- .../stl/trex_stl_lib/trex_stl_sim.py | 4 +- .../stl/trex_stl_lib/utils/parsing_opts.py | 18 +++++--- scripts/exp/imix_3pkt_vm.pcap | Bin 4588 -> 4588 bytes scripts/exp/udp_1pkt_range_clients_split.pcap | Bin 7624 -> 7624 bytes scripts/exp/udp_1pkt_src_ip_split.pcap | Bin 3824 -> 3824 bytes scripts/exp/udp_1pkt_tuple_gen_split.pcap | Bin 7624 -> 7624 bytes scripts/stl/tests/multi_core_test.py | 48 ++++++++++----------- src/rpc-server/commands/trex_rpc_cmd_stream.cpp | 45 +++++++++++++++++++ src/rpc-server/commands/trex_rpc_cmds.h | 1 + 10 files changed, 108 insertions(+), 45 deletions(-) diff --git a/scripts/automation/regression/functional_tests/stl_basic_tests.py b/scripts/automation/regression/functional_tests/stl_basic_tests.py index e9409baf..28178324 100644 --- a/scripts/automation/regression/functional_tests/stl_basic_tests.py +++ b/scripts/automation/regression/functional_tests/stl_basic_tests.py @@ -253,12 +253,12 @@ class CStlBasic_Test(functional_general_test.CGeneralFunctional_Test): ["udp_3pkt_pcap.py","-m 1 -l 10",True, False], #["udp_1pkt_simple.py","-m 1 -l 3",True], ["udp_1pkt_pcap_relative_path.py","-m 1 -l 3",True, False], - ["udp_1pkt_tuple_gen_split.py","-m 1 -c 2 -l 100",True], - ["udp_1pkt_range_clients_split.py","-m 1 -c 2 -l 100",True], - ["udp_1pkt_vxlan.py","-m 1 -c 1 -l 17",True, False], # can't generate: no VXLAN in Scapy, only in profile - ["udp_1pkt_ipv6_in_ipv4.py","-m 1 -c 1 -l 17",True], - ["yaml/imix_3pkt.yaml","-m 50kpps --limit 20 --cores 2",True], - ["yaml/imix_3pkt_vm.yaml","-m 50kpps --limit 20 --cores 2",True], + ["udp_1pkt_tuple_gen_split.py","-m 1 -l 100",True], + ["udp_1pkt_range_clients_split.py","-m 1 -l 100",True], + ["udp_1pkt_vxlan.py","-m 1 -l 17",True, False], # can't generate: no VXLAN in Scapy, only in profile + ["udp_1pkt_ipv6_in_ipv4.py","-m 1 -l 17",True], + ["yaml/imix_3pkt.yaml","-m 50kpps --limit 20",True], + ["yaml/imix_3pkt_vm.yaml","-m 50kpps --limit 20",True], ["udp_1pkt_simple_mac_dst.py","-m 1 -l 1 ",True], ["udp_1pkt_simple_mac_src.py","-m 1 -l 1 ",True], ["udp_1pkt_simple_mac_dst_src.py","-m 1 -l 1 ",True], @@ -271,13 +271,12 @@ class CStlBasic_Test(functional_general_test.CGeneralFunctional_Test): ["udp_1pkt_simple_test.py","-m 1 -l 10 ",True, False], ["udp_1pkt_mac_mask5.py","-m 1 -l 30 ",True], ["udp_1pkt_range_clients_split_garp.py","-m 1 -l 50",True], - ["udp_1pkt_src_ip_split.py","-m 1 -l 50 --cores 2",True], + ["udp_1pkt_src_ip_split.py","-m 1 -l 50",True], ["udp_1pkt_repeat_random.py","-m 1 -l 50",True], ]; p1 = [ ["udp_1pkt_repeat_random.py","-m 1 -l 50",True] ]; - for obj in p: try: test_generated = obj[3] @@ -337,13 +336,29 @@ class CStlBasic_Test(functional_general_test.CGeneralFunctional_Test): def test_multicore_scheduling (self): - mc_tests = ['stl/tests/single_cont.py', + + seed = time.time() + + # test with simple vars + rc = self.run_sim('stl/tests/multi_core_test.py', output = None, options = '--test_multi_core --limit=840 -t test_type=plain#seed={0} -m 27kpps'.format(seed), silent = True) + assert_equal(rc, True) + + + # test with tuple + rc = self.run_sim('stl/tests/multi_core_test.py', output = None, options = '--test_multi_core --limit=840 -t test_type=tuple#seed={0} -m 27kpps'.format(seed), silent = True) + assert_equal(rc, True) + + # some tests + mc_tests = [ + 'stl/tests/single_cont.py', 'stl/tests/single_burst.py', 'stl/tests/multi_burst.py', - 'stl/tests/many_streams.py', ] for mc_test in mc_tests: - rc = self.run_sim(mc_test, output = None, options = '--test_multi_core --limit=3840 -m 27kpps', silent = True) + rc = self.run_sim(mc_test, output = None, options = '--test_multi_core --limit=840 -m 27kpps', silent = True) assert_equal(rc, True) + return + + 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 0394cf43..63a1232b 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 @@ -111,8 +111,6 @@ class STLSim(object): # handle YAMLs if tunables == None: tunables = {} - else: - tunables = tunables[0] for input_file in input_files: try: @@ -556,7 +554,7 @@ def test_multi_core (r, options): duration = options.duration, mode = 'none', silent = True, - tunables = [{'seed': 5}]) + tunables = options.tunables) print("") diff --git a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py index e1de6b55..65333e0f 100755 --- a/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py +++ b/scripts/automation/trex_control_plane/stl/trex_stl_lib/utils/parsing_opts.py @@ -213,19 +213,25 @@ def is_valid_file(filename): return filename -def decode_tunables_to_dict (**kwargs): - return kwargs def decode_tunables (tunable_str): - try: - tunables = [eval('decode_tunables_to_dict({0})'.format(t)) for t in tunable_str.split('#')] + tunables = {} - except (SyntaxError, NameError): - raise argparse.ArgumentTypeError("bad syntax for tunables: {0}".format(tunable_str)) + # split by diaz to tokens + tokens = tunable_str.split('#') + + # each token is of form X=Y + for token in tokens: + print(token) + m = re.search('(.*)=(.*)', token) + if not m: + raise argparse.ArgumentTypeError("bad syntax for tunables: {0}".format(token)) + tunables[m.group(1)] = m.group(2) return tunables + OPTIONS_DB = {MULTIPLIER: ArgumentPack(['-m', '--multiplier'], {'help': match_multiplier_help, 'dest': "mult", diff --git a/scripts/exp/imix_3pkt_vm.pcap b/scripts/exp/imix_3pkt_vm.pcap index 4a97280d7654363887c13bac57f8006249a8e01f..de78d5755e659a406e9ed2680aaaf3b1f8917e46 100644 GIT binary patch delta 206 zcmaE({6<;!%Hd55nHX3YVBi8f0|O(BGx;N@?nE!2iI3zaZqc87lUa5XV-M5hEH1gp ztC;mCC-TZ}{>H4qHu(py++-Ur{mB#gWG8oU=`k_nOjh8MnS6yyZ}S~K1E$GFy!wo} zV4*r*pllw9$@l|gI1@uYSX_(`C|&?&Ch_Sr7J^ypfUNY*28?=4lX(Pz@qI5g>^YAX5SW86-AG delta 200 zcmaE({6<;!%Hd55nHX3YVBmi}0|O(BGx;N@-b8P2Ce9y|6}V(3Zqc7OU3L>=4-*sT zPmsXmRm}PmAIon3#;n1{#Q6&-Ih#v%@;W~K&CJ~TOp|#8fpY)Aa!WwW{~#vQ QQpU*%%sNb53_zX)0Lr&HDF6Tf diff --git a/scripts/exp/udp_1pkt_range_clients_split.pcap b/scripts/exp/udp_1pkt_range_clients_split.pcap index fb5037cc7a64a79fc05c2a3f43255b38b2c2d298..203de6ebcd3af27d24472a94ba213f1aa73903cd 100644 GIT binary patch literal 7624 zcmajjM{b)}7=__qU6dtDa<^P0TfO(*sNQ?;HNAJI+D`EXvH;r~$RN`U5+EDMAX6jR zNph4#gM-}jp9>HK0rDBW{PtW<9$^U^|A8d=}MO7qsA z-=~MHbh5sImF}%aMVTQhgRHM%Wq7OPc~;2EBCnFv`~WIckF<*maXaza)% zSr1`ld+V>Z+>n(Z>nm6ZZ$14fFJ$GA^(CwvZw(IThpY=^eF5u2ymj_HdK&INm#oiW z<$7x{+S)anX=q=HGK3NZ7<$FtXUqIF;unN2-x-TT_V_1dW65U@S z>myi~ycM+vyT44sh$_D`b5D>q@+pdN!nS0`vYVS?|NT>Mb$vuaWg0tZUv9 z^Zq(n@4~w7Ez$iAvfhDp!&{>Jn`FHW>!!Cv_eEsA1*^zgqWfE9y$S1OR(;HOLSjK)+ww~Z;9^9$U1>l<}J~EIa$ZB%DpAJuORCPR)x1j_myNF!m9L^ z=)Q`q16Wn@*7?RCnD^CW?Zc|}mgv5QtUXvY-V)u{lC=w~)?1?cIleG@3*;``2Zy{?9R*Sd9 ze&0&gDy-IcD+9kBV!v-AYXw%Dx5R$mPS!H4c5nR=zSnk;wFIlfTMxtc+D@_-VRd?| zIDD_|B5MIwm$yXs-DJ(f>h_lCzK5(iSUuhn-S?6;3#->#qWeCwW?=PsOLX5))-zPKS0(LtO0L{?gz=5gf-|b(S4Gv30O&QiSCEU8izIHEz$ijS!1w`PYiS8H3 z>Vmc4Ez$iVS)H&Jy(PL|BC7+|QoNO|yI&@&9oDk9ME5IXwZU5Pmgs(!tX5d7-V)uf zk<|ig&0C`Tb+Vdat$Ry!zd=?LtPO98?l;M5gth4{(ft-#4Y0PnCA!}xs~*<2w?y|l zWYxjiiMJBE`(3hXVeNWLbiYSd4XizHiSGBws)n`iEz$h}SyiwOyd}CnB&!nEp|?c$ mM`TsNI`Wq2{+O(CSjXNH-Jg(E2J6IIqWe>_N@1PGTYm#Hme14x literal 7624 zcmajjXHS-A7{>9N&55Ak76)#eIMRmZNfS+zzU<4|UG3g`*@<0#fxdDA?um+9wrtv- zU3S-M_x=p_pe@Of^gf^CPM#2whhP3L4z66eFLXCI<|g^c$aAGGNpePh!Ov^|`;`Cl zB+12#NltNceUj7+e{FSzZLFS zwrH!f+ET0}pDlY6UHRHt*Hn^XWwx^AzoTobwvww$Q>>(bEqeo91=^}_DNC_3+t~8o z(6ueQHM0Gb-50WDucNC_TlML?-_Dl*imvV2T9v;0BDQP;x{9=QDSh|#Z22$fs@GOs z`tFO_vO07XYpW`K_YG|M&**BAP=a%YQ;wqqeSGmAd;9w(M1O zm1ry2{SLPLM|ADb)~f5qr2G#hqu8=n&^0Q%m5cK}*!@nn{0DUH)K;+jQnu`6bd_o= z*!?cH{Cjlm(pIqhGPdj`bd_l%ex3+@wel%P5BDzLvD>(1>u;rK0wMSdQ zc|V3NTaT_W+GivSrVqYpk|{-5+4fzd_dlZ3Vj@$Cf>du5sE5c7Kp9 z{~BEfwH54sJX`h*y2fiO*!>~4{3~=F%5II^_)~U2fh~I)T@$nw?EWxY{w2B&Yb)6O zM7HcHbWPM&u=^&q{0nq7X)D1-n1SmVb(_W7(~Oe~|u0G*H*Cm zlWh4%=sKybVD~fFvWL($LtDY_PqF16qU%(4t1#Yu6Fp!PZN` diff --git a/scripts/exp/udp_1pkt_src_ip_split.pcap b/scripts/exp/udp_1pkt_src_ip_split.pcap index 08ba764e55018e5be617c9348ae8b6f0ff4fd7eb..af254c452daa2e48c54e1baea69b25eed9dbfe49 100644 GIT binary patch literal 3824 zcma*p$4&xK7zN-n`*v2#yF}6?8B86vJ$uAHKWFq{>nzeBcFa;7{GEnOu!^2 z#>W4p>e*T!u$_PBer}<{itUW|sI22wood~|3UDi+TDP!*+zP7J4Xk=@ z)vMMutOjm1sMZy%5Vu0AbqOoXt*~lcz>07yqFU#$8oAY|T4%7L+={B!DXb=LHL2DK ztQfaqs&x#jnOn`Obp$KUt+;9(!fN4Gi)tOfN^mQoTKlk)+)Ap}9;_6%QmR#k)yl0_ z)!K#C#;rEh+JV*1t#;MghLz@4TD7)dWw@15txZ^2Ze>+#16BvOI#g>NRwuVQRcj4a z7q_}pYZX?GTRGKQfz{2eZq-_b)x)hG)mnnp%dKA3T7;G7R$jFhU=_GkP_21becb9( vtvOglZWUE)7FLN{CDodN)z7Vd)tZJiz%4wrV*4LG1#6I7gQ_(NYlvIFJ`RxX literal 3824 zcma*p$4-Jl6b0Y`K|xSJ5fOVAR1|wn-1t0h-4T25ed)s9dtdnqzKtW3^-PBNKH z=FXR!nazBC-tOCt!=&?_G{%-*U>^7z{#3%LxXiFI@!ztcz|coF4zyx8Y{qLM$&t~2 zNqd&oAgnQN+5dX8wBBLaxs{<>1F*)qmA*mCzTRMEaLcLo)emceTbZi$3d_N*EY<3R zHOVcPYQ4a6a?7n+y|AXZg^E-x-|-ohncVWIRu8OcZh2Mf304-ja#X7u)(p3DRqGL! zi(5X`>Vh@PEx&3#z;bgdpjw@<=D3xoTKBNBxs|V49kAxP6;!P|SRQT_s8&0y1#X2@ z>lT)mTZO9C25XU9Vb!{UmBXzf)k?rx;#Nepu3_bJt5~&KVJ&m3M76G9`M6c8S}m|v zxK*ZFm$3ZYDp##ItW|DRsMZCn0Jkbts~OfBx2ja@99AB;s#U8A);hOpRO<{@KDTOB zs}a@)x9U{u6jqR1^{N$vwaKjp)jEMyz^$liMPY4mE2dh>dRRN$imTQktT4A)RI3iwF1N6oise8009FyV5~@`TYmZw$$^ns; diff --git a/scripts/exp/udp_1pkt_tuple_gen_split.pcap b/scripts/exp/udp_1pkt_tuple_gen_split.pcap index 873ab47fedc0301a72e7e25242b78bf362dc6f59..2b7c7976d31d095a3f0c5595013d9a12db13e673 100644 GIT binary patch literal 7624 zcma*rS8mi`7)D{IPeOo%8ba?q^cGs^z4zW0z%6&Ig)Ja@xncucups^n8J!FC+UJw3 zktO@lZ~IuX=FhM9@4Bnrsx!X_s;aBAQ+|)kY$NR%Yfq~>Q&khwhfR%6{v0VM>?~Vv zS2bLXzkU7Yzv+05){kO!*IV5)YiqQ=7pte<>ao_hV)fQrojcgLuCK-FtGD{>y1o>v zzuxM%*5_gk)LSKu_B3AOr((70t(LVu7HhEH8no7jVhz<>L)N1E?$rG(YtenQhOI^S z(VA^7x{uZzYtenQ=30yHqg9@Cdm3A%`)G|?i|(T}&suaJt@+lX`)Dn&7Tx!x?iX5% z?xVHHT67<+#nz(xXpLEm?xVHDT67<+acj|iw3b?n?xVHLT67<+<<_G6Xsxgo-S?*M zS6YkiqqWLfbRVtN)}s4pt+5u}M{BLM=ssHOtVQ?HT5m17kJbij(S5WwT8r+ZwaHp^ z-yEYPK3aFJMfcIVXDzyq)_rTyeY74}i|(WK&{}jql)8UpExM1^V{6fUw4PXt?xXe8 jT67<+XV#+oXg#+U-AC(%wdg)tFRexQ(RyVqx{uahNIfa2 literal 7624 zcma*rS8mi$97b_xGD#*OKtc_n_a1r+E%e@dZwug+x2%ONAbNRX3+xAO21eflI-c{F ztdS-Arz`th$(mn3-@R>A&8joMr>m-`b5eef{5wY4GuEC~b*8E&W-gl=o%}IUZrE9l zW=}O-jZeRR^WSv5uGZ&b_19aCe{1V%eJ@s{-s-j1r(zA%Tb(D^bzR?z)mv}%*>!y^ zR;%9Xx7OEUHS4VbYkerzV7=9{)|X=S)mwwsdS9%edTYp9>ApeT&$3p!M{C$x=^m}w z)=Kwi&9PRxM{BON(mh(`O}D4(eoXghjan<+qczW3=^m~5)=KwiEwEO)@1^b+S}Wb7 zwa8lO9<9aJO801uSu5S6wZvNK9<6a}rF*oNS}Wb7wai-S9`Qvt##H)_h_xRR=P)PgSFBEAN9&}u(mh(I ztd;K3I&H0Vk5>72u{~W|P4{S>wN|=sQTOMpmG03xZ>@BX)&*;&d$cZEE8U}Y$y(_i zt;^O*_h?#4QU hJzCGKmG04cZmo2W)(dN;d$e9!E8U~@%3A3jtv{>kDo+3a diff --git a/scripts/stl/tests/multi_core_test.py b/scripts/stl/tests/multi_core_test.py index 17896b5e..918a30bf 100644 --- a/scripts/stl/tests/multi_core_test.py +++ b/scripts/stl/tests/multi_core_test.py @@ -24,7 +24,7 @@ class STLMultiCore(object): mode = STLTXCont(pps = pps)) - def generate_var (self, rng, i, vm, pkt_offset): + def generate_var (self, rng, i, vm, pkt_offset, verbose = False): name = "var-{0}".format(i) @@ -36,7 +36,7 @@ class STLMultiCore(object): step = rng.randint(1, 1000) op = rng.choice(['inc', 'dec']) - vm += [STLVmFlowVar(name = str(i), + vm += [STLVmFlowVar(name = name, min_value = min_value, max_value = max_value, size = size, @@ -44,17 +44,18 @@ class STLMultiCore(object): STLVmWrFlowVar(fv_name = name, pkt_offset = pkt_offset), ] - print('name: {:}, start: {:}, end: {:}, size: {:}, op: {:}, step {:}'.format(name, - min_value, - max_value, - size, - op, - step)) + if verbose: + print('name: {:}, start: {:}, end: {:}, size: {:}, op: {:}, step {:}'.format(name, + min_value, + max_value, + size, + op, + step)) return size - def generate_tuple_var (self, rng, i, vm, pkt_offset): + def generate_tuple_var (self, rng, i, vm, pkt_offset, verbose = False): name = "tuple-{0}".format(i) # ip @@ -74,11 +75,12 @@ class STLMultiCore(object): STLVmWrFlowVar (fv_name = name + ".port", pkt_offset = (pkt_offset + 4) ), ] - print('name: {:}, ip_start: {:}, ip_end: {:}, port_start: {:}, port_end: {:}'.format(name, - ip_min, - ip_max, - port_min, - port_max)) + if verbose: + print('name: {:}, ip_start: {:}, ip_end: {:}, port_start: {:}, port_end: {:}'.format(name, + ip_min, + ip_max, + port_min, + port_max)) return 8 @@ -88,27 +90,23 @@ class STLMultiCore(object): def get_streams (self, direction = 0, **kwargs): rng = random.Random(kwargs.get('seed', 1)) + test_type = kwargs.get('test_type', 'plain') - var_type = kwargs.get('var_type', 'plain') - - - var_type = 'tuple' - vm = [] # base offset pkt_offset = 42 - print("\nusing the following vars:\n") - if var_type == 'plain': + vm = [] + + if test_type == 'plain': for i in range(20): pkt_offset += self.generate_var(rng, i, vm, pkt_offset) - else: + elif test_type == 'tuple': for i in range(5): pkt_offset += self.generate_tuple_var(rng, i, vm, pkt_offset) + else: + raise STLError('unknown mutli core test type') - - - print("\n") # create imix streams return [self.create_stream(x['size'], x['pps'],x['isg'] , vm) for x in self.streams_def] diff --git a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp index e5072b9e..becd51c5 100644 --- a/src/rpc-server/commands/trex_rpc_cmd_stream.cpp +++ b/src/rpc-server/commands/trex_rpc_cmd_stream.cpp @@ -252,6 +252,51 @@ TrexRpcCmdAddStream::parse_vm_instr_tuple_flow_var(const Json::Value &inst, std: } +/** + * if a user specify min_value and max_value with a step + * that does not create a full cycle - pad the values to allow + * a true cycle + * + */ +void +TrexRpcCmdAddStream::handle_range_padding(uint64_t &max_value, + uint64_t &min_value, + uint64_t step, + int op, + Json::Value &result) { + + /* pad for the step */ + uint64_t pad = (max_value - min_value + 1) % step; + if (pad == 0) { + return; + } + + /* the leftover rounded up */ + uint64_t step_pad = step - pad; + + switch (op) { + case StreamVmInstructionFlowMan::FLOW_VAR_OP_INC: + + if ( (UINT64_MAX - max_value) < step_pad ) { + generate_parse_err(result, "VM: could not pad range to be a true cycle - '(max_value - min_value + 1) % step' should be zero"); + } + max_value += step_pad; + + break; + + case StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC: + if ( min_value < step_pad ) { + generate_parse_err(result, "VM: could not pad range to be a true cycle - '(max_value - min_value + 1) % step' should be zero"); + } + min_value -= step_pad; + + break; + + default: + break; + } +} + void TrexRpcCmdAddStream::check_min_max(uint8_t flow_var_size, uint64_t init_value, diff --git a/src/rpc-server/commands/trex_rpc_cmds.h b/src/rpc-server/commands/trex_rpc_cmds.h index c987f325..506bd2c9 100644 --- a/src/rpc-server/commands/trex_rpc_cmds.h +++ b/src/rpc-server/commands/trex_rpc_cmds.h @@ -114,6 +114,7 @@ void parse_vm_instr_trim_pkt_size(const Json::Value &inst, std::unique_ptr &stream, Json::Value &result); void parse_vm_instr_write_flow_var(const Json::Value &inst, std::unique_ptr &stream, Json::Value &result); void parse_vm_instr_write_mask_flow_var(const Json::Value &inst, std::unique_ptr &stream, Json::Value &result); +void handle_range_padding(uint64_t &max_value, uint64_t &min_value, uint64_t step, int op, Json::Value &result); ); -- 2.16.6