trex_stateless_gtest.cpp revision d5084206
1/*
2 Hanoch Haim
3 Cisco Systems, Inc.
4*/
5
6/*
7Copyright (c) 2015-2015 Cisco Systems, Inc.
8
9Licensed under the Apache License, Version 2.0 (the "License");
10you may not use this file except in compliance with the License.
11You may obtain a copy of the License at
12
13    http://www.apache.org/licenses/LICENSE-2.0
14
15Unless required by applicable law or agreed to in writing, software
16distributed under the License is distributed on an "AS IS" BASIS,
17WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
18See the License for the specific language governing permissions and
19limitations under the License.
20*/
21
22#include "bp_sim.h"
23#include "flow_stat_parser.h"
24#include <common/gtest.h>
25#include <common/basic_utils.h>
26#include <trex_stateless.h>
27#include <trex_stateless_dp_core.h>
28#include <trex_stateless_messaging.h>
29#include <trex_streams_compiler.h>
30#include <trex_stream_node.h>
31#include <trex_stream.h>
32#include <trex_stateless_port.h>
33#include <trex_rpc_server_api.h>
34#include <iostream>
35#include <vector>
36
37
38
39
40class CPcapLoader {
41public:
42    CPcapLoader();
43    ~CPcapLoader();
44
45
46public:
47    bool load_pcap_file(std::string file,int pkt_id=0);
48    void update_ip_src(uint32_t ip_addr);
49    void clone_packet_into_stream(TrexStream * stream);
50    void dump_packet();
51
52public:
53    bool                    m_valid;
54    CCapPktRaw              m_raw;
55    CPacketIndication       m_pkt_indication;
56};
57
58CPcapLoader::~CPcapLoader(){
59}
60
61bool CPcapLoader::load_pcap_file(std::string cap_file,int pkt_id){
62    m_valid=false;
63    CPacketParser parser;
64
65    CCapReaderBase * lp=CCapReaderFactory::CreateReader((char *)cap_file.c_str(),0);
66
67    if (lp == 0) {
68        printf(" ERROR file %s does not exist or not supported \n",(char *)cap_file.c_str());
69        return false;
70    }
71
72    int cnt=0;
73    bool found =false;
74
75
76    while ( true ) {
77        /* read packet */
78        if ( lp->ReadPacket(&m_raw) ==false ){
79            break;
80        }
81        if (cnt==pkt_id) {
82            found = true;
83            break;
84        }
85        cnt++;
86    }
87    if ( found ){
88        if ( parser.ProcessPacket(&m_pkt_indication, &m_raw) ){
89            m_valid = true;
90        }
91    }
92
93    delete lp;
94    return (m_valid);
95}
96
97void CPcapLoader::update_ip_src(uint32_t ip_addr){
98
99    if ( m_pkt_indication.l3.m_ipv4 ) {
100        m_pkt_indication.l3.m_ipv4->setSourceIp(ip_addr);
101        m_pkt_indication.l3.m_ipv4->updateCheckSum();
102    }
103}
104
105void CPcapLoader::clone_packet_into_stream(TrexStream * stream){
106
107    uint16_t pkt_size=m_raw.getTotalLen();
108
109    uint8_t      *binary = new uint8_t[pkt_size];
110    memcpy(binary,m_raw.raw,pkt_size);
111    stream->m_pkt.binary = binary;
112    stream->m_pkt.len    = pkt_size;
113}
114
115
116
117
118CPcapLoader::CPcapLoader(){
119
120}
121
122void CPcapLoader::dump_packet(){
123    if (m_valid ) {
124        m_pkt_indication.Dump(stdout,1);
125    }else{
126        fprintf(stdout," no packets were found \n");
127    }
128}
129
130
131
132
133class basic_vm  : public testing::Test {
134    protected:
135     virtual void SetUp() {
136     }
137     virtual void TearDown() {
138     }
139   public:
140};
141
142
143TEST_F(basic_vm, cache_basic) {
144
145    CGenNodeStateless *node = new CGenNodeStateless();
146
147    node->cache_mbuf_array_init();
148    int i;
149    node->cache_mbuf_array_alloc(10);
150    for (i=0; i<10; i++) {
151        rte_mbuf_t * m =CGlobalInfo::pktmbuf_alloc_small(0);
152        m->data_off=i;
153        node->cache_mbuf_array_set(i,(rte_mbuf_t *) m);
154    }
155
156    for (i=0; i<10; i++) {
157      rte_mbuf_t * m =node->cache_mbuf_array_get_cur();
158      printf(" %d \n",m->data_off);
159    }
160
161    node->cache_mbuf_array_free();
162
163    delete node;
164}
165
166
167TEST_F(basic_vm, pkt_size) {
168
169    EXPECT_EQ(calc_writable_mbuf_size(36,62),62);
170    EXPECT_EQ(calc_writable_mbuf_size(63,62),62);
171    EXPECT_EQ(calc_writable_mbuf_size(45,65),65);
172    EXPECT_EQ(calc_writable_mbuf_size(66,65),65);
173    EXPECT_EQ(calc_writable_mbuf_size(62,128),128);
174    EXPECT_EQ(calc_writable_mbuf_size(62,252),63);
175    EXPECT_EQ(calc_writable_mbuf_size(121,252),122);
176    EXPECT_EQ(calc_writable_mbuf_size(253,252),254);
177    EXPECT_EQ(calc_writable_mbuf_size(250,252),252);
178    EXPECT_EQ(calc_writable_mbuf_size(184,252),185);
179}
180
181
182/* start/stop/stop back to back */
183TEST_F(basic_vm, vm0) {
184
185    StreamVm vm;
186
187    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(20) );
188    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",8,
189                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,0,1,7 )
190                        );
191    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",14, 0,true)
192                        );
193
194    vm.Dump(stdout);
195}
196
197TEST_F(basic_vm, vm1) {
198
199    StreamVm vm;
200
201    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",1,
202                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,0,1,7 )
203                        );
204    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true)
205                        );
206    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
207
208    vm.compile(128);
209
210
211    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
212
213    printf (" program size : %lu \n",(ulong)program_size);
214
215
216    vm.Dump(stdout);
217
218}
219
220TEST_F(basic_vm, vm2) {
221
222    StreamVm vm;
223
224    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",1,
225                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,5,1,7 )
226                        );
227    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true)
228                        );
229    //vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
230
231    vm.compile(128);
232
233
234    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
235
236    printf (" program size : %lu \n",(ulong)program_size);
237
238
239    vm.Dump(stdout);
240
241    uint8_t test_udp_pkt[14+20+4+4]={
242        0x00,0x00,0x00,0x01,0x00,0x00,
243        0x00,0x00,0x00,0x01,0x00,0x00,
244        0x08,0x00,
245
246        0x45,0x00,0x00,0x81, /*14 */
247        0xaf,0x7e,0x00,0x00, /*18 */
248        0x12,0x11,0xd9,0x23, /*22 */
249        0x01,0x01,0x01,0x01, /*26 */
250        0x3d,0xad,0x72,0x1b, /*30 */
251
252        0x11,0x11,
253        0x11,0x11,
254
255        0x00,0x6d,
256        0x00,0x00,
257    };
258
259
260
261    StreamDPVmInstructionsRunner runner;
262
263    uint8_t ex[]={5,
264                 6,
265                 7,
266                 1,
267                 2,
268                 3,
269                 4,
270                 5,
271                 6,
272                 7,
273                 1,
274                 2,
275                 3,
276                 4,
277                 5,
278                 6,
279                 7,
280                 1,
281                 2,
282                 3};
283
284    uint32_t random_per_thread=0;
285    int i;
286    for (i=0; i<20; i++) {
287        runner.run(&random_per_thread,
288                   program_size,
289                   vm.get_dp_instruction_buffer()->get_program(),
290                   vm.get_bss_ptr(),
291                   test_udp_pkt);
292        EXPECT_EQ(test_udp_pkt[26],ex[i]);
293    }
294
295}
296
297
298TEST_F(basic_vm, vm3) {
299
300    StreamVm vm;
301
302    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",4 /* size */,
303                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,5,1,7 )
304                        );
305    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true)
306                        );
307    //vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
308
309    vm.compile(128);
310
311
312    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
313
314    printf (" program size : %lu \n",(ulong)program_size);
315
316
317    vm.Dump(stdout);
318
319    #define PKT_TEST_SIZE (14+20+4+4)
320    uint8_t test_udp_pkt[PKT_TEST_SIZE]={
321        0x00,0x00,0x00,0x01,0x00,0x00,
322        0x00,0x00,0x00,0x01,0x00,0x00,
323        0x08,0x00,
324
325        0x45,0x00,0x00,0x81, /*14 */
326        0xaf,0x7e,0x00,0x00, /*18 */
327        0x12,0x11,0xd9,0x23, /*22 */
328        0x01,0x01,0x01,0x01, /*26 */
329        0x3d,0xad,0x72,0x1b, /*30 */
330
331        0x11,0x11,
332        0x11,0x11,
333
334        0x00,0x6d,
335        0x00,0x00,
336    };
337
338
339
340    StreamDPVmInstructionsRunner runner;
341
342    uint8_t ex[]={5,
343                 6,
344                 7,
345                 1,
346                 2,
347                 3,
348                 4,
349                 5,
350                 6,
351                 7,
352                 1,
353                 2,
354                 3,
355                 4,
356                 5,
357                 6,
358                 7,
359                 1,
360                 2,
361                 3};
362
363    uint32_t random_per_thread=0;
364
365    int i;
366    for (i=0; i<20; i++) {
367        runner.run(&random_per_thread,
368                   program_size,
369                   vm.get_dp_instruction_buffer()->get_program(),
370                   vm.get_bss_ptr(),
371                   test_udp_pkt);
372
373        fprintf(stdout," %d \n",i);
374        //utl_DumpBuffer(stdout,test_udp_pkt,PKT_TEST_SIZE,0);
375        /* big */
376        EXPECT_EQ(test_udp_pkt[29],ex[i]);
377        EXPECT_EQ(test_udp_pkt[28],0);
378        EXPECT_EQ(test_udp_pkt[27],0);
379        EXPECT_EQ(test_udp_pkt[26],0);
380    }
381
382}
383
384TEST_F(basic_vm, vm4) {
385
386    StreamVm vm;
387
388    vm.add_instruction( new StreamVmInstructionFlowMan( "var1", 8 /* size */,
389                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,5,1,7 )
390                        );
391    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,false)
392                        );
393    //vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
394
395    vm.compile(128);
396
397
398    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
399
400    printf (" program size : %lu \n",(ulong)program_size);
401
402
403    vm.Dump(stdout);
404
405    #define PKT_TEST_SIZE (14+20+4+4)
406    uint8_t test_udp_pkt[PKT_TEST_SIZE]={
407        0x00,0x00,0x00,0x01,0x00,0x00,
408        0x00,0x00,0x00,0x01,0x00,0x00,
409        0x08,0x00,
410
411        0x45,0x00,0x00,0x81, /*14 */
412        0xaf,0x7e,0x00,0x00, /*18 */
413        0x12,0x11,0xd9,0x23, /*22 */
414        0x01,0x01,0x01,0x01, /*26 */
415        0x3d,0xad,0x72,0x1b, /*30 */
416
417        0x11,0x11,
418        0x11,0x11,
419
420        0x00,0x6d,
421        0x00,0x00,
422    };
423
424
425
426    StreamDPVmInstructionsRunner runner;
427
428    uint8_t ex[]={5,
429                 6,
430                 7,
431                 1,
432                 2,
433                 3,
434                 4,
435                 5,
436                 6,
437                 7,
438                 1,
439                 2,
440                 3,
441                 4,
442                 5,
443                 6,
444                 7,
445                 1,
446                 2,
447                 3};
448
449    uint32_t random_per_thread=0;
450
451    int i;
452    for (i=0; i<20; i++) {
453        runner.run(&random_per_thread,
454                   program_size,
455                   vm.get_dp_instruction_buffer()->get_program(),
456                   vm.get_bss_ptr(),
457                   test_udp_pkt);
458
459        fprintf(stdout," %d \n",i);
460        utl_DumpBuffer(stdout,test_udp_pkt,PKT_TEST_SIZE,0);
461        /* not big */
462        EXPECT_EQ(test_udp_pkt[33],0);
463        EXPECT_EQ(test_udp_pkt[32],0);
464        EXPECT_EQ(test_udp_pkt[31],0);
465        EXPECT_EQ(test_udp_pkt[30],0);
466        EXPECT_EQ(test_udp_pkt[29],0);
467        EXPECT_EQ(test_udp_pkt[28],0);
468        EXPECT_EQ(test_udp_pkt[27],0);
469        EXPECT_EQ(test_udp_pkt[26],ex[i]);
470    }
471
472}
473
474
475/* two fields */
476TEST_F(basic_vm, vm5) {
477
478    StreamVm vm;
479
480    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",4 /* size */,
481                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,5,1,7 )
482                        );
483
484    vm.add_instruction( new StreamVmInstructionFlowMan( "var2",1 /* size */,
485                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC,24,23,27 ) );
486
487    /* src ip */
488    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true)
489                        );
490
491    /* change TOS */
492    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var2",15, 0,true)
493                        );
494
495    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
496
497    vm.compile(128);
498
499
500    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
501
502    printf (" program size : %lu \n",(ulong)program_size);
503
504
505    vm.Dump(stdout);
506
507    #define PKT_TEST_SIZE (14+20+4+4)
508    uint8_t test_udp_pkt[PKT_TEST_SIZE]={
509        0x00,0x00,0x00,0x01,0x00,0x00,
510        0x00,0x00,0x00,0x01,0x00,0x00,
511        0x08,0x00,
512
513        0x45,0x00,0x00,0x81, /*14 */
514        0xaf,0x7e,0x00,0x00, /*18 */
515        0x12,0x11,0xd9,0x23, /*22 */
516        0x01,0x01,0x01,0x01, /*26 */
517        0x3d,0xad,0x72,0x1b, /*30 */
518
519        0x11,0x11,           /*34 */
520        0x11,0x11,
521
522        0x00,0x6d,
523        0x00,0x00,
524    };
525
526
527
528    StreamDPVmInstructionsRunner runner;
529
530    uint8_t ex[]={5,
531                 6,
532                 7,
533                 1,
534                 2,
535                 3,
536                 4,
537                 5,
538                 6,
539                 7,
540                 1,
541                 2,
542                 3,
543                 4,
544                 5,
545                 6,
546                 7,
547                 1,
548                 2,
549                 3};
550
551         uint8_t ex_tos[]={0x18,
552                      0x17,
553                      0x1b,
554                      0x1a,
555                      0x19,
556                      0x18,
557                      0x17,
558                      0x1b,
559                     0x1a,
560                     0x19,
561                     0x18,
562                     0x17,
563             0x1b,
564            0x1a,
565            0x19,
566            0x18,
567            0x17,
568             0x1b,
569            0x1a,
570            0x19,
571            0x18,
572            0x17,
573
574             0x1b,
575            0x1a,
576            0x19,
577            0x18,
578            0x17,
579
580             0x1b,
581            0x1a,
582            0x19,
583            0x18,
584            0x17,
585
586             0x1b,
587            0x1a,
588            0x19,
589            0x18,
590            0x17,
591         };
592
593    uint32_t random_per_thread=0;
594
595    int i;
596    for (i=0; i<20; i++) {
597        runner.run(&random_per_thread,
598                   program_size,
599                   vm.get_dp_instruction_buffer()->get_program(),
600                   vm.get_bss_ptr(),
601                   test_udp_pkt);
602
603        fprintf(stdout," %d \n",i);
604        //utl_DumpBuffer(stdout,test_udp_pkt,PKT_TEST_SIZE,0);
605        /* not big */
606        EXPECT_EQ(test_udp_pkt[29],ex[i]);
607        EXPECT_EQ(test_udp_pkt[28],0);
608        EXPECT_EQ(test_udp_pkt[27],0);
609        EXPECT_EQ(test_udp_pkt[26],0);
610
611        /* check tos */
612        EXPECT_EQ(test_udp_pkt[15],ex_tos[i]);
613    }
614}
615
616/* -load file, write to file  */
617TEST_F(basic_vm, vm6) {
618
619
620
621    StreamVm vm;
622
623    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",4 /* size */,
624                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,0x10000001,0x10000001,0x100000fe)
625                        );
626
627    vm.add_instruction( new StreamVmInstructionFlowMan( "var2",1 /* size */,
628                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC,24,23,27 ) );
629
630    /* src ip */
631    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var1",26, 0,true)
632                        );
633
634    /* change TOS */
635    vm.add_instruction( new StreamVmInstructionWriteToPkt( "var2",15, 0,true)
636                        );
637
638    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
639
640    vm.compile(128);
641
642
643    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
644
645    printf (" program size : %lu \n",(ulong)program_size);
646
647
648    vm.Dump(stdout);
649
650    CPcapLoader pcap;
651    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
652
653
654
655    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm6.pcap");
656    assert(lpWriter);
657
658
659    StreamDPVmInstructionsRunner runner;
660
661    uint32_t random_per_thread=0;
662
663    int i;
664    for (i=0; i<20; i++) {
665        runner.run(&random_per_thread,
666                   program_size,
667                   vm.get_dp_instruction_buffer()->get_program(),
668                   vm.get_bss_ptr(),
669                   (uint8_t*)pcap.m_raw.raw);
670
671        //utl_DumpBuffer(stdout,pcap.m_raw.raw,pcap.m_raw.pkt_len,0);
672        assert(lpWriter->write_packet(&pcap.m_raw));
673    }
674
675    delete lpWriter;
676
677    CErfCmp cmp;
678
679    bool res1=cmp.compare("exp/udp_64B_vm6.pcap","exp/udp_64B_vm6-ex.pcap");
680    EXPECT_EQ(1, res1?1:0);
681}
682
683/* test client command */
684TEST_F(basic_vm, vm7) {
685
686
687
688    StreamVm vm;
689
690    vm.add_instruction( new StreamVmInstructionFlowClient( "cl1",
691                                                           0x10000001,
692                                                           0x10000004,
693                                                           1025,
694                                                           1027,
695                                                           100,
696                                                           0) );
697
698    /* src ip */
699    vm.add_instruction( new StreamVmInstructionWriteToPkt( "cl1.ip",26, 0,true)
700                        );
701
702    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
703
704    /* src port */
705    vm.add_instruction( new StreamVmInstructionWriteToPkt( "cl1.port",34, 0,true)
706                        );
707
708    vm.compile(128);
709
710
711    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
712
713    printf (" program size : %lu \n",(ulong)program_size);
714
715
716    vm.Dump(stdout);
717
718    CPcapLoader pcap;
719    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
720
721
722
723    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm7.pcap");
724    assert(lpWriter);
725
726
727    StreamDPVmInstructionsRunner runner;
728
729    uint32_t random_per_thread=0;
730
731    int i;
732    for (i=0; i<20; i++) {
733        runner.run(&random_per_thread,
734                   program_size,
735                   vm.get_dp_instruction_buffer()->get_program(),
736                   vm.get_bss_ptr(),
737                   (uint8_t*)pcap.m_raw.raw);
738
739        assert(lpWriter->write_packet(&pcap.m_raw));
740    }
741
742    delete lpWriter;
743
744    CErfCmp cmp;
745
746    bool res1=cmp.compare("exp/udp_64B_vm7.pcap","exp/udp_64B_vm7-ex.pcap");
747    EXPECT_EQ(1, res1?1:0);
748}
749
750
751////////////////////////////////////////////////////////
752
753TEST_F(basic_vm, vm_mask_err) {
754
755    bool fail=false;
756    /* should fail */
757
758    try {
759        StreamVm vm;
760        vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
761        vm.compile(128);
762        uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
763        printf(" program_size : %lu \n",(ulong)program_size);
764     } catch (const TrexException &ex) {
765        fail=true;
766    }
767
768     EXPECT_EQ(true, fail);
769}
770
771
772TEST_F(basic_vm, vm_mask1) {
773
774
775
776    StreamVm vm;
777
778    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",4 /* size */,
779                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,0x10000007,0x10000007,0x100000fe)  );
780
781
782    vm.add_instruction( new StreamVmInstructionWriteMaskToPkt("var1", 36,2,0x00ff,0,0,1) );
783
784    vm.compile(128);
785
786
787    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
788
789    printf (" program size : %lu \n",(ulong)program_size);
790
791
792    vm.Dump(stdout);
793
794    CPcapLoader pcap;
795    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
796
797
798    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm_mask1.pcap");
799    assert(lpWriter);
800
801
802    StreamDPVmInstructionsRunner runner;
803
804    uint32_t random_per_thread=0;
805
806    int i;
807    for (i=0; i<20; i++) {
808        runner.run(&random_per_thread,
809                   program_size,
810                   vm.get_dp_instruction_buffer()->get_program(),
811                   vm.get_bss_ptr(),
812                   (uint8_t*)pcap.m_raw.raw);
813
814        assert(lpWriter->write_packet(&pcap.m_raw));
815    }
816
817    delete lpWriter;
818
819    CErfCmp cmp;
820
821    bool res1=cmp.compare("exp/udp_64B_vm_mask1.pcap","exp/udp_64B_vm_mask1-ex.pcap");
822    EXPECT_EQ(1, res1?1:0);
823}
824
825
826TEST_F(basic_vm, vm_mask2) {
827
828
829
830    StreamVm vm;
831
832    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",4 /* size */,
833                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,0x10000007,0x10000007,0x100000fe)  );
834
835
836    vm.add_instruction( new StreamVmInstructionWriteMaskToPkt("var1", 36,2,0xff00,8,0,1) );
837
838    vm.compile(128);
839
840
841    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
842
843    printf (" program size : %lu \n",(ulong)program_size);
844
845
846    vm.Dump(stdout);
847
848    CPcapLoader pcap;
849    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
850
851
852    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm_mask2.pcap");
853    assert(lpWriter);
854
855
856    StreamDPVmInstructionsRunner runner;
857
858    uint32_t random_per_thread=0;
859
860    int i;
861    for (i=0; i<20; i++) {
862        runner.run(&random_per_thread,
863                   program_size,
864                   vm.get_dp_instruction_buffer()->get_program(),
865                   vm.get_bss_ptr(),
866                   (uint8_t*)pcap.m_raw.raw);
867
868        assert(lpWriter->write_packet(&pcap.m_raw));
869    }
870
871    delete lpWriter;
872
873    CErfCmp cmp;
874
875    bool res1=cmp.compare("exp/udp_64B_vm_mask2.pcap","exp/udp_64B_vm_mask2-ex.pcap");
876    EXPECT_EQ(1, res1?1:0);
877}
878
879TEST_F(basic_vm, vm_mask3) {
880
881
882
883    StreamVm vm;
884
885    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",4 /* size */,
886                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,0x10000007,0x10000007,0x100000fe)  );
887
888
889    vm.add_instruction( new StreamVmInstructionWriteMaskToPkt("var1", 36,1,0x2,1,0,1) );
890
891    vm.compile(128);
892
893
894    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
895
896    printf (" program size : %lu \n",(ulong)program_size);
897
898
899    vm.Dump(stdout);
900
901    CPcapLoader pcap;
902    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
903
904
905    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm_mask3.pcap");
906    assert(lpWriter);
907
908
909    StreamDPVmInstructionsRunner runner;
910
911    uint32_t random_per_thread=0;
912
913    int i;
914    for (i=0; i<20; i++) {
915        runner.run(&random_per_thread,
916                   program_size,
917                   vm.get_dp_instruction_buffer()->get_program(),
918                   vm.get_bss_ptr(),
919                   (uint8_t*)pcap.m_raw.raw);
920
921        assert(lpWriter->write_packet(&pcap.m_raw));
922    }
923
924    delete lpWriter;
925
926    CErfCmp cmp;
927
928    bool res1=cmp.compare("exp/udp_64B_vm_mask3.pcap","exp/udp_64B_vm_mask3-ex.pcap");
929    EXPECT_EQ(1, res1?1:0);
930}
931
932TEST_F(basic_vm, vm_mask4) {
933
934
935
936    StreamVm vm;
937
938    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",1 /* size */,
939                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,1,1,10)  );
940
941
942    vm.add_instruction( new StreamVmInstructionWriteMaskToPkt("var1", 36,2,0xFF00,8,0,1) );
943
944    vm.compile(128);
945
946
947    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
948
949    printf (" program size : %lu \n",(ulong)program_size);
950
951
952    vm.Dump(stdout);
953
954    CPcapLoader pcap;
955    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
956
957
958    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm_mask4.pcap");
959    assert(lpWriter);
960
961
962    StreamDPVmInstructionsRunner runner;
963
964    uint32_t random_per_thread=0;
965
966    int i;
967    for (i=0; i<20; i++) {
968        runner.run(&random_per_thread,
969                   program_size,
970                   vm.get_dp_instruction_buffer()->get_program(),
971                   vm.get_bss_ptr(),
972                   (uint8_t*)pcap.m_raw.raw);
973
974        assert(lpWriter->write_packet(&pcap.m_raw));
975    }
976
977    delete lpWriter;
978
979    CErfCmp cmp;
980
981    bool res1=cmp.compare("exp/udp_64B_vm_mask4.pcap","exp/udp_64B_vm_mask4-ex.pcap");
982    EXPECT_EQ(1, res1?1:0);
983}
984
985TEST_F(basic_vm, vm_mask5) {
986
987
988
989    StreamVm vm;
990
991    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",1 /* size */,
992                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,1,1,10)  );
993
994
995    vm.add_instruction( new StreamVmInstructionWriteMaskToPkt("var1", 36,4,0x00FF0000,16,0,1) );
996
997    vm.compile(128);
998
999
1000    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
1001
1002    printf (" program size : %lu \n",(ulong)program_size);
1003
1004
1005    vm.Dump(stdout);
1006
1007    CPcapLoader pcap;
1008    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
1009
1010
1011    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm_mask5.pcap");
1012    assert(lpWriter);
1013
1014
1015    StreamDPVmInstructionsRunner runner;
1016
1017    uint32_t random_per_thread=0;
1018
1019    int i;
1020    for (i=0; i<20; i++) {
1021        runner.run(&random_per_thread,
1022                   program_size,
1023                   vm.get_dp_instruction_buffer()->get_program(),
1024                   vm.get_bss_ptr(),
1025                   (uint8_t*)pcap.m_raw.raw);
1026
1027        assert(lpWriter->write_packet(&pcap.m_raw));
1028    }
1029
1030    delete lpWriter;
1031
1032    CErfCmp cmp;
1033
1034    bool res1=cmp.compare("exp/udp_64B_vm_mask5.pcap","exp/udp_64B_vm_mask5-ex.pcap");
1035    EXPECT_EQ(1, res1?1:0);
1036}
1037
1038
1039TEST_F(basic_vm, vm_mask6) {
1040
1041
1042
1043    StreamVm vm;
1044
1045    vm.add_instruction( new StreamVmInstructionFlowMan( "var1",4 /* size */,
1046                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,1,1,20)  );
1047
1048
1049    vm.add_instruction( new StreamVmInstructionWriteMaskToPkt("var1", 36,2,0x00FF,-1,0,1) );
1050
1051    vm.compile(128);
1052
1053
1054    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
1055
1056    printf (" program size : %lu \n",(ulong)program_size);
1057
1058
1059    vm.Dump(stdout);
1060
1061    CPcapLoader pcap;
1062    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
1063
1064
1065    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm_mask6.pcap");
1066    assert(lpWriter);
1067
1068
1069    StreamDPVmInstructionsRunner runner;
1070
1071    uint32_t random_per_thread=0;
1072
1073    int i;
1074    for (i=0; i<20; i++) {
1075        runner.run(&random_per_thread,
1076                   program_size,
1077                   vm.get_dp_instruction_buffer()->get_program(),
1078                   vm.get_bss_ptr(),
1079                   (uint8_t*)pcap.m_raw.raw);
1080
1081        assert(lpWriter->write_packet(&pcap.m_raw));
1082    }
1083
1084    delete lpWriter;
1085
1086    CErfCmp cmp;
1087
1088    bool res1=cmp.compare("exp/udp_64B_vm_mask6.pcap","exp/udp_64B_vm_mask6-ex.pcap");
1089    EXPECT_EQ(1, res1?1:0);
1090}
1091
1092////////////////////////////////////////////////////////
1093
1094
1095TEST_F(basic_vm, vm8) {
1096
1097
1098
1099    StreamVm vm;
1100
1101    vm.add_instruction( new StreamVmInstructionFlowClient( "cl1",
1102                                                           0x10000001,
1103                                                           0x10000006,
1104                                                           1025,
1105                                                           1027,
1106                                                           4,
1107                                                           0) );
1108
1109    /* src ip */
1110    vm.add_instruction( new StreamVmInstructionWriteToPkt( "cl1.ip",26, 0,true)
1111                        );
1112
1113    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
1114
1115    /* src port */
1116    vm.add_instruction( new StreamVmInstructionWriteToPkt( "cl1.port",34, 0,true)
1117                        );
1118
1119
1120    vm.compile(128);
1121
1122
1123    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
1124
1125    printf (" program size : %lu \n",(ulong)program_size);
1126
1127
1128    vm.Dump(stdout);
1129
1130    CPcapLoader pcap;
1131    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
1132
1133
1134
1135    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm8.pcap");
1136    assert(lpWriter);
1137
1138
1139    StreamDPVmInstructionsRunner runner;
1140
1141    uint32_t random_per_thread=0;
1142
1143    int i;
1144    for (i=0; i<20; i++) {
1145        runner.run(&random_per_thread,
1146                   program_size,
1147                   vm.get_dp_instruction_buffer()->get_program(),
1148                   vm.get_bss_ptr(),
1149                   (uint8_t*)pcap.m_raw.raw);
1150
1151        assert(lpWriter->write_packet(&pcap.m_raw));
1152    }
1153
1154    delete lpWriter;
1155
1156    CErfCmp cmp;
1157
1158    bool res1=cmp.compare("exp/udp_64B_vm8.pcap","exp/udp_64B_vm8-ex.pcap");
1159    EXPECT_EQ(1, res1?1:0);
1160}
1161
1162static void vm_build_program_seq(StreamVm & vm,
1163                                 uint16_t packet_size,
1164                                 bool should_compile){
1165
1166    vm.add_instruction( new StreamVmInstructionFlowClient( "tuple_gen",
1167                                                           0x10000001,
1168                                                           0x10000006,
1169                                                           1025,
1170                                                           1027,
1171                                                           20,
1172                                                           0) );
1173
1174    /* src ip */
1175    vm.add_instruction( new StreamVmInstructionWriteToPkt( "tuple_gen.ip",26, 0,true)
1176                        );
1177
1178    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
1179
1180    /* src port */
1181    vm.add_instruction( new StreamVmInstructionWriteToPkt( "tuple_gen.port",34, 0,true)
1182                        );
1183
1184    if (should_compile) {
1185        vm.compile(packet_size);
1186    }
1187}
1188
1189
1190TEST_F(basic_vm, vm9) {
1191
1192
1193    StreamVm vm;
1194
1195    vm_build_program_seq(vm,128, true);
1196
1197    printf(" max packet update %lu \n",(ulong)vm.get_max_packet_update_offset());
1198
1199    EXPECT_EQ(36,vm.get_max_packet_update_offset());
1200
1201    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
1202
1203    printf (" program size : %lu \n",(ulong)program_size);
1204
1205
1206    vm.Dump(stdout);
1207
1208    CPcapLoader pcap;
1209    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
1210
1211
1212
1213    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm9.pcap");
1214    assert(lpWriter);
1215
1216
1217    StreamDPVmInstructionsRunner runner;
1218
1219    uint32_t random_per_thread=0;
1220
1221    int i;
1222    for (i=0; i<30; i++) {
1223        runner.run(&random_per_thread,
1224                   program_size,
1225                   vm.get_dp_instruction_buffer()->get_program(),
1226                   vm.get_bss_ptr(),
1227                   (uint8_t*)pcap.m_raw.raw);
1228
1229        assert(lpWriter->write_packet(&pcap.m_raw));
1230    }
1231
1232    delete lpWriter;
1233
1234    CErfCmp cmp;
1235
1236    bool res1=cmp.compare("exp/udp_64B_vm9.pcap","exp/udp_64B_vm9-ex.pcap");
1237    EXPECT_EQ(1, res1?1:0);
1238}
1239
1240
1241/* test vmDP object */
1242TEST_F(basic_vm, vm10) {
1243
1244    StreamVm vm;
1245
1246    vm_build_program_seq(vm,128, true);
1247
1248    printf(" max packet update %lu \n",(ulong)vm.get_max_packet_update_offset());
1249
1250    EXPECT_EQ(36,vm.get_max_packet_update_offset());
1251
1252    StreamVmDp * lpDpVm =vm.generate_dp_object();
1253
1254    EXPECT_EQ(lpDpVm->get_bss_size(),vm.get_bss_size());
1255
1256    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
1257
1258    printf (" program size : %lu \n",(ulong)program_size);
1259
1260
1261    vm.Dump(stdout);
1262
1263    CPcapLoader pcap;
1264    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
1265
1266
1267
1268    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/udp_64B_vm9.pcap");
1269    assert(lpWriter);
1270
1271
1272    StreamDPVmInstructionsRunner runner;
1273
1274    uint32_t random_per_thread=0;
1275
1276    int i;
1277    for (i=0; i<30; i++) {
1278
1279        runner.run(&random_per_thread,
1280                   lpDpVm->get_program_size(),
1281                   lpDpVm->get_program(),
1282                   lpDpVm->get_bss(),
1283                   (uint8_t*)pcap.m_raw.raw);
1284
1285        assert(lpWriter->write_packet(&pcap.m_raw));
1286    }
1287
1288    delete lpWriter;
1289
1290    CErfCmp cmp;
1291    delete  lpDpVm;
1292
1293    bool res1=cmp.compare("exp/udp_64B_vm9.pcap","exp/udp_64B_vm9-ex.pcap");
1294    EXPECT_EQ(1, res1?1:0);
1295}
1296
1297
1298/* test vmDP object */
1299TEST_F(basic_vm, vm_syn_attack) {
1300
1301    StreamVm vm;
1302    srand(0x1234);
1303
1304    vm.add_instruction( new StreamVmInstructionFlowMan( "ip_src",
1305                                                        4,
1306                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM,
1307                                                        0,
1308                                                        0,
1309                                                        1000000));
1310
1311    vm.add_instruction( new StreamVmInstructionFlowMan( "ip_dst",
1312                                                        4,
1313                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM,
1314                                                        0,
1315                                                        0,
1316                                                        1000000));
1317
1318    vm.add_instruction( new StreamVmInstructionFlowMan( "src_port",
1319                                                        2,
1320                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM,
1321                                                        0,
1322                                                        1025,
1323                                                        65000));
1324
1325    vm.add_instruction( new StreamVmInstructionFlowMan( "dst_port",
1326                                                        2,
1327                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM,
1328                                                        0,
1329                                                        1025,
1330                                                        65000));
1331
1332    /* src ip */
1333    vm.add_instruction( new StreamVmInstructionWriteToPkt( "ip_src",26, 0x10000000,true)
1334                        );
1335
1336    vm.add_instruction( new StreamVmInstructionWriteToPkt( "ip_dst",26+4, 0x40000000,true)
1337                        );
1338
1339    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
1340
1341    /* src port */
1342    vm.add_instruction( new StreamVmInstructionWriteToPkt( "src_port",34, 0,true)
1343                        );
1344    vm.add_instruction( new StreamVmInstructionWriteToPkt( "dst_port",34+2, 0,true)
1345                        );
1346
1347    vm.compile(128);
1348
1349    printf(" max packet update %lu \n",(ulong)vm.get_max_packet_update_offset());
1350
1351    EXPECT_EQ(38,vm.get_max_packet_update_offset());
1352
1353    StreamVmDp * lpDpVm =vm.generate_dp_object();
1354
1355    EXPECT_EQ(lpDpVm->get_bss_size(),vm.get_bss_size());
1356
1357    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
1358
1359    printf (" program size : %lu \n",(ulong)program_size);
1360
1361
1362    vm.Dump(stdout);
1363
1364    CPcapLoader pcap;
1365    pcap.load_pcap_file("stl/yaml/syn_packet.pcap",0);
1366
1367
1368
1369    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)"exp/stl_syn_attack.pcap");
1370    assert(lpWriter);
1371
1372
1373    StreamDPVmInstructionsRunner runner;
1374
1375    uint32_t random_per_thread=0;
1376
1377    int i;
1378    for (i=0; i<30; i++) {
1379
1380        runner.run(&random_per_thread,
1381                   lpDpVm->get_program_size(),
1382                   lpDpVm->get_program(),
1383                   lpDpVm->get_bss(),
1384                   (uint8_t*)pcap.m_raw.raw);
1385
1386        assert(lpWriter->write_packet(&pcap.m_raw));
1387    }
1388
1389    delete lpWriter;
1390
1391    CErfCmp cmp;
1392    delete  lpDpVm;
1393
1394    bool res1=cmp.compare("exp/stl_syn_attack.pcap","exp/stl_syn_attack-ex.pcap");
1395    EXPECT_EQ(1, res1?1:0);
1396}
1397
1398
1399void run_vm_program( StreamVm & vm,
1400                    std::string input_pcap_file,
1401                    std::string out_file_name,
1402                    int num_pkts
1403                    ){
1404
1405    CPcapLoader pcap;
1406    pcap.load_pcap_file(input_pcap_file,0);
1407
1408    printf(" packet size : %lu \n",(ulong)pcap.m_raw.pkt_len);
1409    vm.compile(pcap.m_raw.pkt_len);
1410
1411    StreamVmDp * lpDpVm =vm.generate_dp_object();
1412
1413    uint32_t program_size=vm.get_dp_instruction_buffer()->get_program_size();
1414
1415    printf (" program size : %lu \n",(ulong)program_size);
1416
1417    vm.Dump(stdout);
1418
1419    std::string out_file_full ="exp/"+out_file_name +".pcap";
1420    std::string out_file_ex_full ="exp/"+out_file_name +"-ex.pcap";
1421
1422    CFileWriterBase * lpWriter=CCapWriterFactory::CreateWriter(LIBPCAP,(char *)out_file_full.c_str());
1423    assert(lpWriter);
1424
1425
1426    StreamDPVmInstructionsRunner runner;
1427
1428    uint32_t random_per_thread=0;
1429
1430    int i;
1431    for (i=0; i<num_pkts; i++) {
1432
1433        runner.run(&random_per_thread,
1434                   lpDpVm->get_program_size(),
1435                   lpDpVm->get_program(),
1436                   lpDpVm->get_bss(),
1437                   (uint8_t*)pcap.m_raw.raw);
1438        uint16_t new_pkt_size=runner.get_new_pkt_size();
1439        assert(new_pkt_size>0);
1440        if (new_pkt_size ==0) {
1441            assert(lpWriter->write_packet(&pcap.m_raw));
1442        }else{
1443            /* we can only reduce */
1444            if (new_pkt_size>pcap.m_raw.pkt_len) {
1445                new_pkt_size=pcap.m_raw.pkt_len;
1446            }
1447            CCapPktRaw np(new_pkt_size);
1448             np.time_sec  = pcap.m_raw.time_sec;
1449             np.time_nsec = pcap.m_raw.time_nsec;
1450             np.pkt_cnt   = pcap.m_raw.pkt_cnt;
1451             memcpy(np.raw,pcap.m_raw.raw,new_pkt_size);
1452             assert(lpWriter->write_packet(&np));
1453        }
1454    }
1455
1456    delete lpWriter;
1457
1458    CErfCmp cmp;
1459    delete  lpDpVm;
1460
1461    bool res1=cmp.compare(out_file_full.c_str() ,out_file_ex_full.c_str());
1462    EXPECT_EQ(1, res1?1:0);
1463}
1464
1465
1466TEST_F(basic_vm, vm_inc_size_64_128) {
1467
1468    StreamVm vm;
1469
1470    vm.add_instruction( new StreamVmInstructionFlowMan( "rand_pkt_size_var",
1471                                                        2,                // size var  must be 16bit size
1472                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,
1473                                                        127,
1474                                                        128,
1475                                                        256));
1476
1477    vm.add_instruction( new StreamVmInstructionChangePktSize( "rand_pkt_size_var"));
1478
1479    /* src ip */
1480    /*14+ 2 , remove the */
1481
1482    vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",16, -14,true)
1483                        );
1484
1485    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
1486
1487    /* update UDP length */
1488    vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",32+6, -(14+20),true)
1489                        );
1490
1491    run_vm_program(vm,"stl/yaml/udp_1518B_no_crc.pcap","stl_vm_inc_size_64_128",20);
1492}
1493
1494TEST_F(basic_vm, vm_random_size_64_128) {
1495
1496    StreamVm vm;
1497    srand(0x1234);
1498
1499    vm.add_instruction( new StreamVmInstructionFlowMan( "rand_pkt_size_var",
1500                                                        2,                // size var  must be 16bit size
1501                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM,
1502                                                        0,
1503                                                        128,
1504                                                        256));
1505
1506    vm.add_instruction( new StreamVmInstructionChangePktSize( "rand_pkt_size_var"));
1507
1508    /* src ip */
1509    /*14+ 2 , remove the */
1510
1511    vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",16, -14,true)
1512                        );
1513
1514    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
1515
1516    /* update UDP length */
1517    vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",32+6, -(14+20),true)
1518                        );
1519
1520
1521    run_vm_program(vm,"stl/yaml/udp_1518B_no_crc.pcap","stl_vm_rand_size_64_128",20);
1522
1523}
1524
1525
1526
1527/* should have exception packet size is smaller than range */
1528TEST_F(basic_vm, vm_random_size_64_127_128) {
1529
1530    StreamVm vm;
1531    srand(0x1234);
1532
1533    vm.add_instruction( new StreamVmInstructionFlowMan( "rand_pkt_size_var",
1534                                                        2,                // size var  must be 16bit size
1535                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM,
1536                                                        127,
1537                                                        128,
1538                                                        256));
1539
1540    vm.add_instruction( new StreamVmInstructionChangePktSize( "rand_pkt_size_var"));
1541
1542    /* src ip */
1543    /*14+ 2 , remove the */
1544
1545    vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",16, -14,true)
1546                        );
1547
1548    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
1549
1550    /* update UDP length */
1551    vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",32+6, -(14+20),true)
1552                        );
1553
1554    bool fail=false;
1555
1556    try {
1557       run_vm_program(vm,"stl/yaml/udp_64B_no_crc.pcap","stl_vm_rand_size_64B_127_128",20);
1558     } catch (const TrexException &ex) {
1559        fail=true;
1560    }
1561
1562    EXPECT_EQ(true, fail);
1563
1564}
1565
1566
1567TEST_F(basic_vm, vm_random_size_500b_0_9k) {
1568
1569    StreamVm vm;
1570    srand(0x1234);
1571
1572    vm.add_instruction( new StreamVmInstructionFlowMan( "rand_pkt_size_var",
1573                                                        2,                // size var  must be 16bit size
1574                                                        StreamVmInstructionFlowMan::FLOW_VAR_OP_RANDOM,
1575                                                        0,
1576                                                        0,
1577                                                        9*1024));
1578
1579    vm.add_instruction( new StreamVmInstructionChangePktSize( "rand_pkt_size_var"));
1580
1581    /* src ip */
1582    /*14+ 2 , remove the */
1583
1584    vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",16, -14,true)
1585                        );
1586
1587    vm.add_instruction( new StreamVmInstructionFixChecksumIpv4(14) );
1588
1589    /* update UDP length */
1590    vm.add_instruction( new StreamVmInstructionWriteToPkt( "rand_pkt_size_var",32+6, -(14+20),true)
1591                        );
1592
1593    run_vm_program(vm,"stl/yaml/udp_594B_no_crc.pcap","stl_vm_rand_size_512B_64_128",10);
1594
1595}
1596
1597
1598
1599//////////////////////////////////////////////////////
1600
1601
1602#define EXPECT_EQ_UINT32(a,b) EXPECT_EQ((uint32_t)(a),(uint32_t)(b))
1603
1604
1605
1606/* basic stateless test */
1607class basic_stl  : public testing::Test {
1608 protected:
1609  virtual void SetUp() {
1610  }
1611  virtual void TearDown() {
1612  }
1613public:
1614};
1615
1616
1617/**
1618 * Queue of RPC msgs for test
1619 *
1620 * @author hhaim
1621 */
1622
1623class CBasicStl;
1624
1625
1626struct CBasicStlDelayCommand {
1627
1628    CBasicStlDelayCommand(){
1629        m_node=NULL;
1630    }
1631    CGenNodeCommand * m_node;
1632};
1633
1634
1635
1636class CBasicStlMsgQueue {
1637
1638friend CBasicStl;
1639
1640public:
1641    CBasicStlMsgQueue(){
1642    }
1643
1644    /* user will allocate the message,  no need to free it by this module */
1645    void add_msg(TrexStatelessCpToDpMsgBase * msg){
1646        m_msgs.push_back(msg);
1647    }
1648
1649    void add_command(CBasicStlDelayCommand & command){
1650        m_commands.push_back(command);
1651    }
1652
1653        /* only if both port are idle we can exit */
1654    void add_command(CFlowGenListPerThread   * core,
1655                     TrexStatelessCpToDpMsgBase * msg,
1656                     double time){
1657
1658        CGenNodeCommand *node = (CGenNodeCommand *)core->create_node() ;
1659
1660        node->m_type = CGenNode::COMMAND;
1661
1662        node->m_cmd = msg;
1663
1664        /* make sure it will be scheduled after the current node */
1665        node->m_time = time ;
1666
1667        CBasicStlDelayCommand command;
1668        command.m_node =node;
1669
1670        add_command(command);
1671    }
1672
1673
1674    void clear(){
1675        m_msgs.clear();
1676        m_commands.clear();
1677    }
1678
1679
1680protected:
1681    std::vector<TrexStatelessCpToDpMsgBase *> m_msgs;
1682
1683    std::vector<CBasicStlDelayCommand> m_commands;
1684};
1685
1686
1687
1688class CBasicStlSink {
1689
1690public:
1691    CBasicStlSink(){
1692        m_core=0;
1693    }
1694    virtual void call_after_init(CBasicStl * m_obj)=0;
1695    virtual void call_after_run(CBasicStl * m_obj)=0;
1696
1697    CFlowGenListPerThread   * m_core;
1698};
1699
1700
1701/**
1702 * handler for DP to CP messages
1703 *
1704 * @author imarom (19-Nov-15)
1705 */
1706class DpToCpHandler {
1707public:
1708    virtual void handle(TrexStatelessDpToCpMsgBase *msg) = 0;
1709};
1710
1711class CBasicStl {
1712
1713public:
1714
1715
1716    CBasicStl(){
1717        m_time_diff=0.001;
1718        m_threads=1;
1719        m_dump_json=false;
1720        m_dp_to_cp_handler = NULL;
1721        m_msg = NULL;
1722        m_sink = NULL;
1723    }
1724
1725
1726    void flush_dp_to_cp_messages() {
1727
1728        CNodeRing *ring = CMsgIns::Ins()->getCpDp()->getRingDpToCp(0);
1729
1730        while ( true ) {
1731            CGenNode * node = NULL;
1732            if (ring->Dequeue(node) != 0) {
1733                break;
1734            }
1735            assert(node);
1736
1737            TrexStatelessDpToCpMsgBase * msg = (TrexStatelessDpToCpMsgBase *)node;
1738            if (m_dp_to_cp_handler) {
1739                m_dp_to_cp_handler->handle(msg);
1740            }
1741
1742            delete msg;
1743        }
1744
1745    }
1746
1747
1748    bool  init(void){
1749
1750        CErfIFStl erf_vif;
1751        fl.Create();
1752        fl.generate_p_thread_info(1);
1753        CFlowGenListPerThread   * lpt;
1754
1755        fl.m_threads_info[0]->set_vif(&erf_vif);
1756
1757        CErfCmp cmp;
1758        cmp.dump=1;
1759
1760        CMessagingManager * cp_dp = CMsgIns::Ins()->getCpDp();
1761
1762        m_ring_from_cp = cp_dp->getRingCpToDp(0);
1763
1764
1765        bool res=true;
1766
1767        lpt=fl.m_threads_info[0];
1768
1769        if ( m_sink ){
1770            m_sink->m_core =lpt;
1771        }
1772
1773        char buf[100];
1774        char buf_ex[100];
1775        sprintf(buf,"%s-%d.erf",CGlobalInfo::m_options.out_file.c_str(),0);
1776        sprintf(buf_ex,"%s-%d-ex.erf",CGlobalInfo::m_options.out_file.c_str(),0);
1777
1778        lpt->start_stateless_simulation_file(buf,CGlobalInfo::m_options.preview);
1779
1780        /* add stream to the queue */
1781        if ( m_msg ) {
1782            assert(m_ring_from_cp->Enqueue((CGenNode *)m_msg)==0);
1783        }
1784        if (m_msg_queue.m_msgs.size()>0) {
1785            for (auto msg : m_msg_queue.m_msgs) {
1786                assert(m_ring_from_cp->Enqueue((CGenNode *)msg)==0);
1787            }
1788        }
1789
1790        if (m_sink) {
1791            m_sink->call_after_init(this);
1792        }
1793
1794        /* add the commands */
1795        if (m_msg_queue.m_commands.size()>0) {
1796            for (auto cmd : m_msg_queue.m_commands) {
1797                /* add commands nodes */
1798                lpt->m_node_gen.add_node((CGenNode *)cmd.m_node);
1799            }
1800        }
1801
1802        lpt->start_stateless_daemon_simulation();
1803        lpt->stop_stateless_simulation_file();
1804
1805        //lpt->m_node_gen.DumpHist(stdout);
1806
1807        cmp.d_sec = m_time_diff;
1808
1809        if ( cmp.compare(std::string(buf),std::string(buf_ex)) != true ) {
1810            res=false;
1811        }
1812
1813        if ( m_dump_json ){
1814            printf(" dump json ...........\n");
1815            std::string s;
1816            fl.m_threads_info[0]->m_node_gen.dump_json(s);
1817            printf(" %s \n",s.c_str());
1818        }
1819
1820        if (m_sink) {
1821            m_sink->call_after_run(this);
1822        }
1823
1824        flush_dp_to_cp_messages();
1825        m_msg_queue.clear();
1826
1827
1828        fl.Delete();
1829        return (res);
1830    }
1831
1832public:
1833    int               m_threads;
1834    double            m_time_diff;
1835    bool              m_dump_json;
1836    DpToCpHandler     *m_dp_to_cp_handler;
1837    CBasicStlSink     * m_sink;
1838
1839    TrexStatelessCpToDpMsgBase * m_msg;
1840    CNodeRing           *m_ring_from_cp;
1841    CBasicStlMsgQueue    m_msg_queue;
1842    CFlowGenList  fl;
1843};
1844
1845
1846
1847TEST_F(basic_stl, load_pcap_file) {
1848    printf (" stateles %d \n",(int)sizeof(CGenNodeStateless));
1849
1850    CPcapLoader pcap;
1851    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
1852    pcap.update_ip_src(0x10000001);
1853    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
1854    pcap.update_ip_src(0x10000001);
1855
1856    //pcap.dump_packet();
1857}
1858
1859
1860
1861class CBBStartPause0: public CBasicStlSink {
1862public:
1863
1864    virtual void call_after_init(CBasicStl * m_obj);
1865    virtual void call_after_run(CBasicStl * m_obj){
1866    };
1867    uint8_t m_port_id;
1868};
1869
1870
1871
1872void CBBStartPause0::call_after_init(CBasicStl * m_obj){
1873
1874    TrexStatelessDpPause * lpPauseCmd = new TrexStatelessDpPause(m_port_id);
1875    TrexStatelessDpResume * lpResumeCmd1 = new TrexStatelessDpResume(m_port_id);
1876
1877    m_obj->m_msg_queue.add_command(m_core,lpPauseCmd, 5.0); /* command in delay of 5 sec */
1878    m_obj->m_msg_queue.add_command(m_core,lpResumeCmd1, 7.0);/* command in delay of 7 sec */
1879
1880}
1881
1882
1883
1884/* start/stop/stop back to back */
1885TEST_F(basic_stl, basic_pause_resume0) {
1886
1887    CBasicStl t1;
1888    CParserOption * po =&CGlobalInfo::m_options;
1889    po->preview.setVMode(7);
1890    po->preview.setFileWrite(true);
1891    po->out_file ="exp/stl_basic_pause_resume0";
1892
1893     TrexStreamsCompiler compile;
1894
1895     uint8_t port_id=0;
1896
1897     std::vector<TrexStream *> streams;
1898
1899     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
1900     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
1901
1902
1903     stream1->m_enabled = true;
1904     stream1->m_self_start = true;
1905     stream1->m_port_id= port_id;
1906
1907
1908     CPcapLoader pcap;
1909     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
1910     pcap.update_ip_src(0x10000001);
1911     pcap.clone_packet_into_stream(stream1);
1912
1913     streams.push_back(stream1);
1914
1915     // stream - clean
1916
1917     std::vector<TrexStreamsCompiledObj *> objs;
1918     assert(compile.compile(port_id, streams, objs));
1919     TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
1920
1921     t1.m_msg_queue.add_msg(lpStartCmd);
1922
1923
1924     CBBStartPause0 sink;
1925     sink.m_port_id = port_id;
1926     t1.m_sink =  &sink;
1927
1928     bool res=t1.init();
1929
1930     delete stream1 ;
1931
1932     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
1933}
1934
1935
1936//////////////////////////////////////////////////////////////
1937
1938
1939class CBBStartStopDelay2: public CBasicStlSink {
1940public:
1941
1942    virtual void call_after_init(CBasicStl * m_obj);
1943    virtual void call_after_run(CBasicStl * m_obj){
1944    };
1945    uint8_t m_port_id;
1946};
1947
1948
1949
1950void CBBStartStopDelay2::call_after_init(CBasicStl * m_obj){
1951
1952    TrexStatelessDpStop * lpStopCmd = new TrexStatelessDpStop(m_port_id);
1953    TrexStatelessDpStop * lpStopCmd1 = new TrexStatelessDpStop(m_port_id);
1954
1955
1956    TrexStreamsCompiler compile;
1957
1958    uint8_t port_id=0;
1959
1960    std::vector<TrexStream *> streams;
1961
1962    TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
1963    stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
1964
1965
1966    stream1->m_enabled = true;
1967    stream1->m_self_start = true;
1968    stream1->m_port_id= port_id;
1969
1970
1971    CPcapLoader pcap;
1972    pcap.load_pcap_file("cap2/udp_64B.pcap",0);
1973    pcap.update_ip_src(0x10000002);
1974    pcap.clone_packet_into_stream(stream1);
1975
1976    streams.push_back(stream1);
1977
1978    // stream - clean
1979    std::vector<TrexStreamsCompiledObj *>objs;
1980    assert(compile.compile(port_id, streams, objs));
1981    TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 1, objs[0], 10.0 /*sec */ );
1982
1983
1984    m_obj->m_msg_queue.add_command(m_core,lpStopCmd, 5.0); /* command in delay of 5 sec */
1985    m_obj->m_msg_queue.add_command(m_core,lpStopCmd1, 7.0);/* command in delay of 7 sec */
1986    m_obj->m_msg_queue.add_command(m_core,lpStartCmd, 7.5);/* command in delay of 7 sec */
1987
1988    delete stream1 ;
1989
1990
1991}
1992
1993
1994
1995/* start/stop/stop back to back */
1996TEST_F(basic_stl, single_pkt_bb_start_stop_delay2) {
1997
1998    CBasicStl t1;
1999    CParserOption * po =&CGlobalInfo::m_options;
2000    po->preview.setVMode(7);
2001    po->preview.setFileWrite(true);
2002    po->out_file ="exp/stl_bb_start_stop_delay2";
2003
2004     TrexStreamsCompiler compile;
2005
2006     uint8_t port_id=0;
2007
2008     std::vector<TrexStream *> streams;
2009
2010     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
2011     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2012
2013
2014     stream1->m_enabled = true;
2015     stream1->m_self_start = true;
2016     stream1->m_port_id= port_id;
2017
2018
2019     CPcapLoader pcap;
2020     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2021     pcap.update_ip_src(0x10000001);
2022     pcap.clone_packet_into_stream(stream1);
2023
2024     streams.push_back(stream1);
2025
2026     // stream - clean
2027     std::vector<TrexStreamsCompiledObj *>objs;
2028     assert(compile.compile(port_id, streams, objs));
2029     TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
2030
2031     t1.m_msg_queue.add_msg(lpStartCmd);
2032
2033
2034     CBBStartStopDelay2 sink;
2035     sink.m_port_id = port_id;
2036     t1.m_sink =  &sink;
2037
2038     bool res=t1.init();
2039
2040     delete stream1 ;
2041
2042     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
2043}
2044
2045
2046
2047
2048
2049
2050
2051class CBBStartStopDelay1: public CBasicStlSink {
2052public:
2053
2054    virtual void call_after_init(CBasicStl * m_obj);
2055    virtual void call_after_run(CBasicStl * m_obj){
2056    };
2057    uint8_t m_port_id;
2058};
2059
2060
2061
2062void CBBStartStopDelay1::call_after_init(CBasicStl * m_obj){
2063
2064    TrexStatelessDpStop * lpStopCmd = new TrexStatelessDpStop(m_port_id);
2065    TrexStatelessDpStop * lpStopCmd1 = new TrexStatelessDpStop(m_port_id);
2066
2067    m_obj->m_msg_queue.add_command(m_core,lpStopCmd, 5.0); /* command in delay of 5 sec */
2068    m_obj->m_msg_queue.add_command(m_core,lpStopCmd1, 7.0);/* command in delay of 7 sec */
2069}
2070
2071
2072
2073/* start/stop/stop back to back */
2074TEST_F(basic_stl, single_pkt_bb_start_stop_delay1) {
2075
2076    CBasicStl t1;
2077    CParserOption * po =&CGlobalInfo::m_options;
2078    po->preview.setVMode(7);
2079    po->preview.setFileWrite(true);
2080    po->out_file ="exp/stl_bb_start_stop_delay1";
2081
2082     TrexStreamsCompiler compile;
2083
2084     uint8_t port_id=0;
2085
2086     std::vector<TrexStream *> streams;
2087
2088     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
2089     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2090
2091
2092     stream1->m_enabled = true;
2093     stream1->m_self_start = true;
2094     stream1->m_port_id= port_id;
2095
2096
2097     CPcapLoader pcap;
2098     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2099     pcap.update_ip_src(0x10000001);
2100     pcap.clone_packet_into_stream(stream1);
2101
2102     streams.push_back(stream1);
2103
2104     // stream - clean
2105     std::vector<TrexStreamsCompiledObj *>objs;
2106     assert(compile.compile(port_id, streams, objs));
2107     TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
2108
2109     t1.m_msg_queue.add_msg(lpStartCmd);
2110
2111
2112     CBBStartStopDelay1 sink;
2113     sink.m_port_id = port_id;
2114     t1.m_sink =  &sink;
2115
2116     bool res=t1.init();
2117
2118     delete stream1 ;
2119
2120     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
2121}
2122
2123
2124/* start/stop/stop back to back */
2125TEST_F(basic_stl, single_pkt_bb_start_stop3) {
2126
2127    CBasicStl t1;
2128    CParserOption * po =&CGlobalInfo::m_options;
2129    po->preview.setVMode(7);
2130    po->preview.setFileWrite(true);
2131    po->out_file ="exp/stl_bb_start_stop3";
2132
2133     TrexStreamsCompiler compile;
2134
2135     uint8_t port_id=0;
2136
2137     std::vector<TrexStream *> streams;
2138
2139     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
2140     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2141
2142
2143     stream1->m_enabled = true;
2144     stream1->m_self_start = true;
2145     stream1->m_port_id= port_id;
2146
2147
2148     CPcapLoader pcap;
2149     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2150     pcap.update_ip_src(0x10000001);
2151     pcap.clone_packet_into_stream(stream1);
2152
2153     streams.push_back(stream1);
2154
2155     // stream - clean
2156     std::vector<TrexStreamsCompiledObj *>objs;
2157     assert(compile.compile(port_id, streams, objs));
2158     TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
2159
2160     TrexStatelessDpStop * lpStopCmd = new TrexStatelessDpStop(port_id);
2161     TrexStatelessDpStop * lpStopCmd1 = new TrexStatelessDpStop(port_id);
2162
2163
2164     t1.m_msg_queue.add_msg(lpStartCmd);
2165     t1.m_msg_queue.add_msg(lpStopCmd);
2166     t1.m_msg_queue.add_msg(lpStopCmd1);
2167
2168     bool res=t1.init();
2169
2170     delete stream1 ;
2171
2172     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
2173}
2174
2175
2176TEST_F(basic_stl, single_pkt_bb_start_stop2) {
2177
2178    CBasicStl t1;
2179    CParserOption * po =&CGlobalInfo::m_options;
2180    po->preview.setVMode(7);
2181    po->preview.setFileWrite(true);
2182    po->out_file ="exp/stl_bb_start_stop2";
2183
2184     TrexStreamsCompiler compile;
2185
2186     uint8_t port_id=0;
2187
2188     std::vector<TrexStream *> streams;
2189
2190     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
2191     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2192
2193
2194     stream1->m_enabled = true;
2195     stream1->m_self_start = true;
2196     stream1->m_port_id= port_id;
2197
2198
2199     CPcapLoader pcap;
2200     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2201     pcap.update_ip_src(0x10000001);
2202     pcap.clone_packet_into_stream(stream1);
2203
2204     streams.push_back(stream1);
2205
2206     // stream - clean
2207     std::vector<TrexStreamsCompiledObj *>objs;
2208     assert(compile.compile(port_id, streams, objs));
2209     TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
2210
2211     TrexStatelessDpStop * lpStopCmd = new TrexStatelessDpStop(port_id);
2212     TrexStatelessDpStart * lpStartCmd1 = new TrexStatelessDpStart(port_id, 0, objs[0]->clone(), 10.0 /*sec */ );
2213
2214
2215     t1.m_msg_queue.add_msg(lpStartCmd);
2216     t1.m_msg_queue.add_msg(lpStopCmd);
2217     t1.m_msg_queue.add_msg(lpStartCmd1);
2218
2219     bool res=t1.init();
2220
2221     delete stream1 ;
2222
2223     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
2224}
2225
2226
2227
2228/* back to back send start/stop */
2229TEST_F(basic_stl, single_pkt_bb_start_stop) {
2230
2231    CBasicStl t1;
2232    CParserOption * po =&CGlobalInfo::m_options;
2233    po->preview.setVMode(7);
2234    po->preview.setFileWrite(true);
2235    po->out_file ="exp/stl_bb_start_stop";
2236
2237     TrexStreamsCompiler compile;
2238
2239     uint8_t port_id=0;
2240
2241     std::vector<TrexStream *> streams;
2242
2243     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
2244     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2245
2246
2247     stream1->m_enabled = true;
2248     stream1->m_self_start = true;
2249     stream1->m_port_id= port_id;
2250
2251
2252     CPcapLoader pcap;
2253     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2254     pcap.update_ip_src(0x10000001);
2255     pcap.clone_packet_into_stream(stream1);
2256
2257     streams.push_back(stream1);
2258
2259     // stream - clean
2260     std::vector<TrexStreamsCompiledObj *>objs;
2261     assert(compile.compile(port_id, streams, objs));
2262     TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
2263
2264     TrexStatelessDpStop * lpStopCmd = new TrexStatelessDpStop(port_id);
2265
2266
2267     t1.m_msg_queue.add_msg(lpStartCmd);
2268     t1.m_msg_queue.add_msg(lpStopCmd);
2269
2270     bool res=t1.init();
2271
2272     delete stream1 ;
2273
2274     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
2275}
2276
2277
2278
2279
2280TEST_F(basic_stl, simple_prog4) {
2281
2282    CBasicStl t1;
2283    CParserOption * po =&CGlobalInfo::m_options;
2284    po->preview.setVMode(7);
2285    po->preview.setFileWrite(true);
2286    po->out_file ="exp/stl_simple_prog4";
2287
2288     TrexStreamsCompiler compile;
2289
2290
2291     std::vector<TrexStream *> streams;
2292
2293
2294     /* stream0 */
2295     TrexStream * stream0 = new TrexStream(TrexStream::stCONTINUOUS, 0,300);
2296     stream0->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2297     stream0->m_enabled = true;
2298     stream0->m_self_start = true;
2299
2300     CPcapLoader pcap;
2301     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2302     pcap.update_ip_src(0x10000000);
2303     pcap.clone_packet_into_stream(stream0);
2304     streams.push_back(stream0);
2305
2306
2307     /* stream1 */
2308     TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,100);
2309     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2310     stream1->set_single_burst(5);
2311     stream1->m_enabled = true;
2312     stream1->m_self_start = true;
2313     stream1->m_next_stream_id=200;
2314
2315     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2316     pcap.update_ip_src(0x10000001);
2317     pcap.clone_packet_into_stream(stream1);
2318
2319     streams.push_back(stream1);
2320
2321
2322     /* stream1 */
2323
2324     TrexStream * stream2 = new TrexStream(TrexStream::stMULTI_BURST, 0,200);
2325     stream2->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2326     stream2->m_isg_usec = 1000000; /*time betwean stream 1 to stream 2 */
2327     stream2->m_enabled = true;
2328     stream2->m_self_start = false;
2329     stream2->set_multi_burst(5,
2330                              3,
2331                              2000000.0);
2332
2333     // next stream is 100 - loop
2334     stream2->m_next_stream_id=100;
2335
2336
2337     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2338     pcap.update_ip_src(0x10000002);
2339     pcap.clone_packet_into_stream(stream2);
2340     streams.push_back(stream2);
2341
2342
2343     uint8_t port_id = 0;
2344     std::vector<TrexStreamsCompiledObj *>objs;
2345     assert(compile.compile(port_id, streams, objs));
2346     TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 0, objs[0], 20.0 /*sec */ );
2347
2348
2349     t1.m_msg = lpStartCmd;
2350
2351     bool res=t1.init();
2352
2353     delete stream0 ;
2354     delete stream1 ;
2355     delete stream2 ;
2356
2357     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
2358}
2359
2360
2361
2362TEST_F(basic_stl, simple_prog3) {
2363
2364    CBasicStl t1;
2365    CParserOption * po =&CGlobalInfo::m_options;
2366    po->preview.setVMode(7);
2367    po->preview.setFileWrite(true);
2368    po->out_file ="exp/stl_simple_prog3";
2369
2370     TrexStreamsCompiler compile;
2371
2372
2373     std::vector<TrexStream *> streams;
2374
2375     /* stream1 */
2376     TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,100);
2377     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2378     stream1->set_single_burst(5);
2379     stream1->m_enabled = true;
2380     stream1->m_self_start = true;
2381     stream1->m_next_stream_id=200;
2382
2383     CPcapLoader pcap;
2384     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2385     pcap.update_ip_src(0x10000001);
2386     pcap.clone_packet_into_stream(stream1);
2387
2388     streams.push_back(stream1);
2389
2390
2391     /* stream1 */
2392
2393     TrexStream * stream2 = new TrexStream(TrexStream::stMULTI_BURST, 0,200);
2394     stream2->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2395     stream2->m_isg_usec = 1000000; /*time betwean stream 1 to stream 2 */
2396     stream2->m_enabled = true;
2397     stream2->m_self_start = false;
2398     stream2->set_multi_burst(5,
2399                              3,
2400                              2000000.0);
2401
2402     // next stream is 100 - loop
2403     stream2->m_next_stream_id=100;
2404
2405
2406     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2407     pcap.update_ip_src(0x10000002);
2408     pcap.clone_packet_into_stream(stream2);
2409     streams.push_back(stream2);
2410
2411
2412     uint8_t port_id = 0;
2413     std::vector<TrexStreamsCompiledObj *>objs;
2414     assert(compile.compile(port_id, streams, objs));
2415     TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 50.0 /*sec */ );
2416
2417
2418     t1.m_msg = lpstart;
2419
2420     bool res=t1.init();
2421
2422     delete stream1 ;
2423     delete stream2 ;
2424
2425     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
2426}
2427
2428
2429TEST_F(basic_stl, simple_prog2) {
2430
2431    CBasicStl t1;
2432    CParserOption * po =&CGlobalInfo::m_options;
2433    po->preview.setVMode(7);
2434    po->preview.setFileWrite(true);
2435    po->out_file ="exp/stl_simple_prog2";
2436
2437     TrexStreamsCompiler compile;
2438
2439
2440     std::vector<TrexStream *> streams;
2441
2442     /* stream1 */
2443     TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,100);
2444     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2445     stream1->set_single_burst(5);
2446     stream1->m_enabled = true;
2447     stream1->m_self_start = true;
2448     stream1->m_next_stream_id=200;
2449
2450     CPcapLoader pcap;
2451     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2452     pcap.update_ip_src(0x10000001);
2453     pcap.clone_packet_into_stream(stream1);
2454
2455     streams.push_back(stream1);
2456
2457
2458     /* stream1 */
2459
2460     TrexStream * stream2 = new TrexStream(TrexStream::stSINGLE_BURST, 0,200);
2461     stream2->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2462     stream2->set_single_burst(5);
2463     stream2->m_isg_usec = 2000000; /*time betwean stream 1 to stream 2 */
2464     stream2->m_enabled = true;
2465     stream2->m_self_start = false;
2466
2467     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2468     pcap.update_ip_src(0x10000002);
2469     pcap.clone_packet_into_stream(stream2);
2470     streams.push_back(stream2);
2471
2472     uint8_t port_id = 0;
2473     std::vector<TrexStreamsCompiledObj *>objs;
2474     assert(compile.compile(port_id, streams, objs));
2475     TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
2476
2477     t1.m_msg = lpstart;
2478
2479     bool res=t1.init();
2480
2481     delete stream1 ;
2482     delete stream2 ;
2483
2484     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
2485}
2486
2487
2488
2489TEST_F(basic_stl, simple_prog1) {
2490
2491    CBasicStl t1;
2492    CParserOption * po =&CGlobalInfo::m_options;
2493    po->preview.setVMode(7);
2494    po->preview.setFileWrite(true);
2495    po->out_file ="exp/stl_simple_prog1";
2496
2497     TrexStreamsCompiler compile;
2498
2499
2500     std::vector<TrexStream *> streams;
2501
2502     /* stream1 */
2503     TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,100);
2504     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2505     stream1->set_single_burst(5);
2506     stream1->m_enabled = true;
2507     stream1->m_self_start = true;
2508     stream1->m_next_stream_id=200;
2509
2510     CPcapLoader pcap;
2511     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2512     pcap.update_ip_src(0x10000001);
2513     pcap.clone_packet_into_stream(stream1);
2514
2515     streams.push_back(stream1);
2516
2517
2518     /* stream1 */
2519
2520     TrexStream * stream2 = new TrexStream(TrexStream::stSINGLE_BURST, 0,200);
2521     stream2->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2522     stream2->set_single_burst(5);
2523     stream2->m_enabled = true;
2524     stream2->m_self_start = false;
2525
2526     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2527     pcap.update_ip_src(0x10000002);
2528     pcap.clone_packet_into_stream(stream2);
2529     streams.push_back(stream2);
2530
2531
2532     uint8_t port_id = 0;
2533     std::vector<TrexStreamsCompiledObj *>objs;
2534     assert(compile.compile(port_id, streams, objs));
2535     TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
2536
2537
2538     t1.m_msg = lpstart;
2539
2540     bool res=t1.init();
2541
2542     delete stream1 ;
2543     delete stream2 ;
2544
2545     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
2546}
2547
2548
2549
2550TEST_F(basic_stl, single_pkt_burst1) {
2551
2552    CBasicStl t1;
2553    CParserOption * po =&CGlobalInfo::m_options;
2554    po->preview.setVMode(7);
2555    po->preview.setFileWrite(true);
2556    po->out_file ="exp/stl_single_pkt_burst1";
2557
2558     TrexStreamsCompiler compile;
2559
2560
2561     std::vector<TrexStream *> streams;
2562
2563     TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,0);
2564     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2565     stream1->set_single_burst(5);
2566     stream1->m_enabled = true;
2567     stream1->m_self_start = true;
2568
2569     CPcapLoader pcap;
2570     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2571     pcap.update_ip_src(0x10000001);
2572     pcap.clone_packet_into_stream(stream1);
2573
2574     streams.push_back(stream1);
2575
2576     uint8_t port_id = 0;
2577     std::vector<TrexStreamsCompiledObj *>objs;
2578     assert(compile.compile(port_id, streams, objs));
2579     TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
2580
2581     t1.m_msg = lpstart;
2582
2583     bool res=t1.init();
2584
2585     delete stream1 ;
2586
2587     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
2588}
2589
2590
2591
2592
2593
2594TEST_F(basic_stl, single_pkt) {
2595
2596    CBasicStl t1;
2597    CParserOption * po =&CGlobalInfo::m_options;
2598    po->preview.setVMode(7);
2599    po->preview.setFileWrite(true);
2600    po->out_file ="exp/stl_single_stream";
2601
2602     TrexStreamsCompiler compile;
2603
2604     uint8_t port_id=0;
2605
2606     std::vector<TrexStream *> streams;
2607
2608     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
2609     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2610
2611
2612     stream1->m_enabled = true;
2613     stream1->m_self_start = true;
2614     stream1->m_port_id= port_id;
2615
2616
2617     CPcapLoader pcap;
2618     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2619     pcap.update_ip_src(0x10000001);
2620     pcap.clone_packet_into_stream(stream1);
2621
2622     streams.push_back(stream1);
2623
2624     // stream - clean
2625
2626     std::vector<TrexStreamsCompiledObj *>objs;
2627     assert(compile.compile(port_id, streams, objs));
2628     TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
2629
2630
2631     t1.m_msg = lpstart;
2632
2633     bool res=t1.init();
2634
2635     delete stream1 ;
2636
2637     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
2638}
2639
2640void test_mac_replace(bool replace_src_by_pkt,
2641                      int replace_dst_mode,
2642                      std::string file){
2643    CBasicStl t1;
2644    CParserOption * po =&CGlobalInfo::m_options;
2645    po->preview.setVMode(7);
2646    po->preview.setFileWrite(true);
2647    po->out_file = file;
2648
2649     TrexStreamsCompiler compile;
2650
2651     uint8_t port_id=0;
2652
2653     std::vector<TrexStream *> streams;
2654
2655     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
2656     stream1->set_override_src_mac_by_pkt_data(replace_src_by_pkt);
2657     stream1->set_override_dst_mac_mode((TrexStream::stream_dst_mac_t)replace_dst_mode);
2658
2659     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2660
2661
2662     stream1->m_enabled = true;
2663     stream1->m_self_start = true;
2664     stream1->m_port_id= port_id;
2665
2666
2667     CPcapLoader pcap;
2668     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2669     pcap.update_ip_src(0x10000001);
2670     pcap.clone_packet_into_stream(stream1);
2671
2672     streams.push_back(stream1);
2673
2674     // stream - clean
2675
2676     std::vector<TrexStreamsCompiledObj *>objs;
2677     assert(compile.compile(port_id, streams, objs));
2678     TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
2679
2680
2681     t1.m_msg = lpstart;
2682
2683     bool res=t1.init();
2684
2685     delete stream1 ;
2686
2687     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
2688}
2689
2690TEST_F(basic_stl, single_pkt_mac0) {
2691
2692    test_mac_replace(false,
2693                     TrexStream::stCFG_FILE,
2694                     "exp/stl_single_stream_mac0");
2695}
2696
2697TEST_F(basic_stl, single_pkt_mac11) {
2698
2699    test_mac_replace(true,
2700                     TrexStream::stPKT,
2701                     "exp/stl_single_stream_mac11");
2702}
2703
2704TEST_F(basic_stl, single_pkt_mac10) {
2705
2706    test_mac_replace(false,
2707                     TrexStream::stPKT,
2708                     "exp/stl_single_stream_mac01");
2709}
2710
2711TEST_F(basic_stl, single_pkt_mac01) {
2712
2713    test_mac_replace(true,
2714                     TrexStream::stCFG_FILE,
2715                     "exp/stl_single_stream_mac10");
2716}
2717
2718
2719TEST_F(basic_stl, multi_pkt1) {
2720
2721    CBasicStl t1;
2722    CParserOption * po =&CGlobalInfo::m_options;
2723    po->preview.setVMode(7);
2724    po->preview.setFileWrite(true);
2725    po->out_file ="exp/stl_multi_pkt1";
2726
2727     TrexStreamsCompiler compile;
2728
2729
2730     std::vector<TrexStream *> streams;
2731
2732     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
2733     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2734
2735
2736     stream1->m_enabled = true;
2737     stream1->m_self_start = true;
2738
2739     CPcapLoader pcap;
2740     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2741     pcap.update_ip_src(0x10000001);
2742     pcap.clone_packet_into_stream(stream1);
2743
2744     streams.push_back(stream1);
2745
2746     TrexStream * stream2 = new TrexStream(TrexStream::stCONTINUOUS,0,1);
2747     stream2->set_rate(TrexStreamRate::RATE_PPS,2.0);
2748
2749     stream2->m_enabled = true;
2750     stream2->m_self_start = true;
2751     stream2->m_isg_usec = 1000.0; /* 1 msec */
2752     pcap.update_ip_src(0x20000001);
2753     pcap.clone_packet_into_stream(stream2);
2754
2755     streams.push_back(stream2);
2756
2757
2758     // stream - clean
2759     uint8_t port_id = 0;
2760     std::vector<TrexStreamsCompiledObj *>objs;
2761     assert(compile.compile(port_id, streams, objs));
2762     TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
2763
2764     t1.m_msg = lpstart;
2765
2766     bool res=t1.init();
2767
2768     delete stream1 ;
2769     delete stream2 ;
2770
2771     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
2772}
2773
2774
2775class CEnableVm {
2776public:
2777    void run(bool full_packet,double duration,uint16_t cache );
2778    CEnableVm() {
2779        m_pg_id = -1;
2780    }
2781public:
2782    std::string    m_input_packet; //"cap2/udp_64B.pcap"
2783    std::string    m_out_file;     //"exp/stl_vm_enable0";
2784    int32_t        m_pg_id; // if >= 0, pg_id for flow stat testing
2785};
2786
2787void CEnableVm::run(bool full_packet,double duration=10.0,uint16_t cache=0){
2788    CFlowStatRuleMgr rule_mgr;
2789    CBasicStl t1;
2790    CParserOption * po =&CGlobalInfo::m_options;
2791    po->preview.setVMode(7);
2792    po->preview.setFileWrite(true);
2793    po->out_file =m_out_file;
2794
2795     TrexStreamsCompiler compile;
2796
2797     uint8_t port_id=0;
2798
2799     std::vector<TrexStream *> streams;
2800
2801     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
2802
2803     if ( cache ){
2804         stream1->m_cache_size=cache;
2805     }
2806
2807     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2808
2809     stream1->m_enabled = true;
2810     stream1->m_self_start = true;
2811     stream1->m_port_id= port_id;
2812
2813     CPcapLoader pcap;
2814     pcap.load_pcap_file(m_input_packet,0);
2815     pcap.update_ip_src(0x10000001);
2816     pcap.clone_packet_into_stream(stream1);
2817
2818     uint16_t pkt_size=pcap.m_raw.pkt_len;
2819
2820     vm_build_program_seq(stream1->m_vm,pkt_size, false);
2821#if 0
2822     if ( full_packet ){
2823         EXPECT_EQ(stream1->m_vm_prefix_size,pkt_size);
2824     }else{
2825         EXPECT_EQ(stream1->m_vm_prefix_size,35);
2826     }
2827#endif
2828
2829     if (m_pg_id >= 0) {
2830         stream1->m_rx_check.m_enabled = true;
2831         stream1->m_rx_check.m_rule_type = TrexPlatformApi::IF_STAT_PAYLOAD;
2832         stream1->m_rx_check.m_pg_id = m_pg_id;
2833         rule_mgr.init_stream(stream1); //different rule_mgr object, but we just want to init fields in stream
2834     } else {
2835         stream1->m_rx_check.m_enabled = false;
2836     }
2837
2838     streams.push_back(stream1);
2839
2840     // stream - clean
2841     std::vector<TrexStreamsCompiledObj *> objs;
2842
2843     assert(compile.compile(port_id,streams, objs) );
2844
2845     TrexStatelessDpStart * lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], duration /*sec */ );
2846
2847
2848     t1.m_msg = lpstart;
2849
2850     bool res=t1.init();
2851
2852     delete stream1 ;
2853
2854     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
2855}
2856
2857TEST_F(basic_stl, vm_enable_cache_10) {
2858
2859    CEnableVm vm_test;
2860    vm_test.m_out_file = "exp/stl_vm_enable0_cache_10";
2861    vm_test.m_input_packet = "cap2/udp_64B.pcap";
2862    vm_test.run(true,10.0,100);
2863}
2864
2865TEST_F(basic_stl, vm_enable_cache_500) {
2866    /* multi mbuf cache */
2867    CEnableVm vm_test;
2868    vm_test.m_out_file = "exp/stl_vm_enable1_cache_500";
2869    vm_test.m_input_packet = "stl/yaml/udp_594B_no_crc.pcap";
2870    vm_test.run(false,20.0,19);
2871}
2872
2873
2874TEST_F(basic_stl, vm_enable0) {
2875
2876    CEnableVm vm_test;
2877    vm_test.m_out_file = "exp/stl_vm_enable0";
2878    vm_test.m_input_packet = "cap2/udp_64B.pcap";
2879    vm_test.run(true);
2880}
2881
2882#if 0
2883// todo: does not work with valgrind, because we need to free the dp->rx message queue in simulation mode
2884TEST_F(basic_stl, vm_enable0_flow_stat) {
2885
2886    CEnableVm vm_test;
2887    vm_test.m_out_file = "exp/stl_vm_enable0_flow_stat";
2888    vm_test.m_input_packet = "cap2/udp_64B.pcap";
2889    vm_test.m_pg_id = 5;
2890    vm_test.run(true);
2891}
2892#endif
2893
2894TEST_F(basic_stl, vm_enable1) {
2895
2896    CEnableVm vm_test;
2897    vm_test.m_out_file = "exp/stl_vm_enable1";
2898    vm_test.m_input_packet = "stl/yaml/udp_594B_no_crc.pcap";
2899    vm_test.run(false);
2900}
2901
2902#if 0
2903//todo: does not work. need to check
2904TEST_F(basic_stl, vm_enable1_flow_stat) {
2905
2906    CEnableVm vm_test;
2907    vm_test.m_out_file = "exp/stl_vm_enable1_flow_stat";
2908    vm_test.m_input_packet = "stl/yaml/udp_594B_no_crc.pcap";
2909    vm_test.m_pg_id = 5;
2910    vm_test.run(false);
2911}
2912#endif
2913
2914TEST_F(basic_stl, vm_enable2) {
2915
2916    CEnableVm vm_test;
2917    vm_test.m_out_file = "exp/stl_vm_enable2";
2918    vm_test.m_input_packet = "cap2/udp_64B.pcap";
2919    vm_test.run(true,50.0);
2920}
2921
2922
2923
2924
2925/* check disabled stream with multiplier of 5*/
2926TEST_F(basic_stl, multi_pkt2) {
2927
2928    CBasicStl t1;
2929    CParserOption * po =&CGlobalInfo::m_options;
2930    po->preview.setVMode(7);
2931    po->preview.setFileWrite(true);
2932    po->out_file ="exp/stl_multi_pkt2";
2933
2934     TrexStreamsCompiler compile;
2935
2936
2937     std::vector<TrexStream *> streams;
2938
2939
2940     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0);
2941     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2942
2943
2944     stream1->m_enabled = true;
2945     stream1->m_self_start = true;
2946
2947     CPcapLoader pcap;
2948     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
2949     pcap.update_ip_src(0x10000001);
2950     pcap.clone_packet_into_stream(stream1);
2951
2952     streams.push_back(stream1);
2953
2954
2955     TrexStream * stream2 = new TrexStream(TrexStream::stCONTINUOUS,0,1);
2956     stream2->set_rate(TrexStreamRate::RATE_PPS,2.0);
2957
2958     stream2->m_enabled = false;
2959     stream2->m_self_start = false;
2960     stream2->m_isg_usec = 1000.0; /* 1 msec */
2961     pcap.update_ip_src(0x20000001);
2962     pcap.clone_packet_into_stream(stream2);
2963
2964     streams.push_back(stream2);
2965
2966
2967     // stream - clean
2968     uint8_t port_id = 0;
2969     std::vector<TrexStreamsCompiledObj *>objs;
2970     assert(compile.compile(port_id, streams, objs, 1, 5.0));
2971     TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ );
2972
2973     t1.m_msg = lpstart;
2974
2975     bool res=t1.init();
2976
2977     delete stream1 ;
2978     delete stream2 ;
2979
2980     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
2981}
2982
2983
2984TEST_F(basic_stl, multi_burst1) {
2985
2986    CBasicStl t1;
2987    CParserOption * po =&CGlobalInfo::m_options;
2988    po->preview.setVMode(7);
2989    po->preview.setFileWrite(true);
2990    po->out_file ="exp/stl_multi_burst1";
2991
2992     TrexStreamsCompiler compile;
2993
2994
2995     std::vector<TrexStream *> streams;
2996
2997     TrexStream * stream1 = new TrexStream(TrexStream::stMULTI_BURST,0,0);
2998     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
2999     stream1->set_multi_burst(5,
3000                              3,
3001                              2000000.0);
3002
3003     stream1->m_enabled = true;
3004     stream1->m_self_start = true;
3005
3006     CPcapLoader pcap;
3007     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
3008     pcap.update_ip_src(0x10000001);
3009     pcap.clone_packet_into_stream(stream1);
3010
3011     streams.push_back(stream1);
3012
3013     uint8_t port_id = 0;
3014     std::vector<TrexStreamsCompiledObj *>objs;
3015     assert(compile.compile(port_id, streams, objs));
3016     TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 40.0 /*sec */ );
3017
3018
3019     t1.m_msg = lpstart;
3020
3021     bool res=t1.init();
3022
3023     delete stream1 ;
3024
3025     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
3026}
3027
3028/********************************************* Itay Tests Start *************************************/
3029
3030/**
3031 * check that continous stream does not point to another stream
3032 * (makes no sense)
3033 */
3034TEST_F(basic_stl, compile_bad_1) {
3035
3036     TrexStreamsCompiler compile;
3037     std::vector<TrexStream *> streams;
3038
3039     TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,2);
3040     stream1->m_enabled = true;
3041     stream1->set_rate(TrexStreamRate::RATE_PPS,52.0);
3042     stream1->m_next_stream_id = 3;
3043
3044     streams.push_back(stream1);
3045
3046     std::string err_msg;
3047     std::vector<TrexStreamsCompiledObj *>objs;
3048     EXPECT_FALSE(compile.compile(0, streams, objs, 1, 1, &err_msg));
3049
3050     delete stream1;
3051
3052}
3053
3054/**
3055 * check for streams pointing to non exsistant streams
3056 *
3057 * @author imarom (16-Nov-15)
3058 */
3059TEST_F(basic_stl, compile_bad_2) {
3060
3061     TrexStreamsCompiler compile;
3062     std::vector<TrexStream *> streams;
3063
3064     TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST,0,1);
3065     stream1->m_enabled = true;
3066     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3067     stream1->set_single_burst(200);
3068
3069     /* non existant next stream */
3070     stream1->m_next_stream_id = 5;
3071
3072     TrexStream * stream2 = new TrexStream(TrexStream::stCONTINUOUS,0,2);
3073     stream1->set_rate(TrexStreamRate::RATE_PPS,52.0);
3074
3075     streams.push_back(stream1);
3076     streams.push_back(stream2);
3077
3078
3079     uint8_t port_id = 0;
3080     std::string err_msg;
3081     std::vector<TrexStreamsCompiledObj *>objs;
3082     EXPECT_FALSE(compile.compile(port_id, streams, objs, 1, 1, &err_msg));
3083
3084
3085     delete stream1;
3086     delete stream2;
3087
3088}
3089
3090/**
3091 * check for "dead streams" in the mesh
3092 * a streams that cannot be reached
3093 *
3094 * @author imarom (16-Nov-15)
3095 */
3096TEST_F(basic_stl, compile_bad_3) {
3097
3098     TrexStreamsCompiler compile;
3099     std::vector<TrexStream *> streams;
3100     TrexStream *stream;
3101
3102     /* stream 1 */
3103     stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 231);
3104     stream->m_enabled = true;
3105     stream->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3106     stream->set_single_burst(200);
3107
3108     stream->m_next_stream_id = 5481;
3109     stream->m_self_start = true;
3110
3111     streams.push_back(stream);
3112
3113     /* stream 2 */
3114     stream = new TrexStream(TrexStream::stCONTINUOUS, 0, 5481);
3115     stream->m_enabled = true;
3116     stream->m_next_stream_id = -1;
3117     stream->m_self_start = false;
3118     stream->set_rate(TrexStreamRate::RATE_PPS,52.0);
3119
3120     streams.push_back(stream);
3121
3122     /* stream 3 */
3123
3124     stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 1928);
3125     stream->m_enabled = true;
3126     stream->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3127     stream->set_single_burst(200);
3128
3129     stream->m_next_stream_id = -1;
3130     stream->m_self_start = true;
3131
3132     streams.push_back(stream);
3133
3134      /* stream 4 */
3135
3136     stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 41231);
3137     stream->m_enabled = true;
3138     stream->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3139     stream->set_single_burst(200);
3140
3141     stream->m_next_stream_id = 3928;
3142     stream->m_self_start = false;
3143
3144     streams.push_back(stream);
3145
3146     /* stream 5 */
3147
3148     stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 3928);
3149     stream->m_enabled = true;
3150     stream->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3151     stream->set_single_burst(200);
3152
3153     stream->m_next_stream_id = 41231;
3154     stream->m_self_start = false;
3155
3156     streams.push_back(stream);
3157
3158     /* compile */
3159     std::string err_msg;
3160     std::vector<TrexStreamsCompiledObj *>objs;
3161     EXPECT_FALSE(compile.compile(0, streams, objs, 1, 1, &err_msg));
3162
3163
3164     for (auto stream : streams) {
3165         delete stream;
3166     }
3167
3168}
3169
3170TEST_F(basic_stl, compile_with_warnings) {
3171
3172    TrexStreamsCompiler compile;
3173     std::vector<TrexStream *> streams;
3174     TrexStream *stream;
3175
3176     /* stream 1 */
3177     stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 231);
3178     stream->m_enabled = true;
3179     stream->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3180     stream->set_single_burst(200);
3181
3182     stream->m_next_stream_id = 1928;
3183     stream->m_self_start = true;
3184
3185     streams.push_back(stream);
3186
3187     /* stream 2 */
3188     stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 5481);
3189     stream->m_enabled = true;
3190     stream->m_next_stream_id = 1928;
3191     stream->m_self_start = true;
3192     stream->set_rate(TrexStreamRate::RATE_PPS,52.0);
3193
3194     streams.push_back(stream);
3195
3196     /* stream 3 */
3197
3198     stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 1928);
3199     stream->m_enabled = true;
3200     stream->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3201     stream->set_single_burst(200);
3202
3203     stream->m_next_stream_id = -1;
3204     stream->m_self_start = true;
3205
3206     streams.push_back(stream);
3207
3208
3209
3210     /* compile */
3211     std::string err_msg;
3212     std::vector<TrexStreamsCompiledObj *>objs;
3213     EXPECT_TRUE(compile.compile(0, streams, objs, 1, 1, &err_msg));
3214     delete objs[0];
3215
3216     EXPECT_TRUE(compile.get_last_compile_warnings().size() == 1);
3217
3218     for (auto stream : streams) {
3219         delete stream;
3220     }
3221
3222}
3223
3224
3225TEST_F(basic_stl, compile_good_stream_id_compres) {
3226
3227     TrexStreamsCompiler compile;
3228     std::vector<TrexStream *> streams;
3229
3230     TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST,0,700);
3231     stream1->m_self_start = true;
3232     stream1->m_enabled = true;
3233     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3234     stream1->set_single_burst(200);
3235
3236     /* non existant next stream */
3237     stream1->m_next_stream_id = 800;
3238
3239
3240     TrexStream * stream2 = new TrexStream(TrexStream::stSINGLE_BURST,0,800);
3241     stream2->set_rate(TrexStreamRate::RATE_PPS,52.0);
3242     stream2->m_enabled = true;
3243     stream2->m_next_stream_id = 700;
3244     stream2->set_single_burst(300);
3245
3246
3247     streams.push_back(stream1);
3248     streams.push_back(stream2);
3249
3250     uint8_t port_id = 0;
3251     std::string err_msg;
3252     std::vector<TrexStreamsCompiledObj *>objs;
3253     EXPECT_TRUE(compile.compile(port_id, streams, objs, 1, 1, &err_msg));
3254
3255     printf(" %s \n",err_msg.c_str());
3256
3257     objs[0]->Dump(stdout);
3258
3259     EXPECT_EQ_UINT32(objs[0]->get_objects()[0].m_stream->m_stream_id,0);
3260     EXPECT_EQ_UINT32(objs[0]->get_objects()[0].m_stream->m_next_stream_id,1);
3261
3262     EXPECT_EQ_UINT32(objs[0]->get_objects()[1].m_stream->m_stream_id,1);
3263     EXPECT_EQ_UINT32(objs[0]->get_objects()[1].m_stream->m_next_stream_id,0);
3264
3265     delete objs[0];
3266
3267     delete stream1;
3268     delete stream2;
3269
3270}
3271
3272
3273
3274class DpToCpHandlerStopEvent: public DpToCpHandler {
3275public:
3276    DpToCpHandlerStopEvent(int event_id) {
3277        m_event_id = event_id;
3278    }
3279
3280    virtual void handle(TrexStatelessDpToCpMsgBase *msg) {
3281        /* first the message must be an event */
3282        TrexDpPortEventMsg *event = dynamic_cast<TrexDpPortEventMsg *>(msg);
3283        EXPECT_TRUE(event != NULL);
3284
3285        EXPECT_TRUE(event->get_event_id() == m_event_id);
3286        EXPECT_TRUE(event->get_port_id() == 0);
3287
3288    }
3289
3290private:
3291    int m_event_id;
3292};
3293
3294TEST_F(basic_stl, dp_stop_event) {
3295
3296    CBasicStl t1;
3297    CParserOption * po =&CGlobalInfo::m_options;
3298    po->preview.setVMode(7);
3299    po->preview.setFileWrite(true);
3300    po->out_file ="exp/ignore";
3301
3302    TrexStreamsCompiler compile;
3303
3304     uint8_t port_id=0;
3305
3306     std::vector<TrexStream *> streams;
3307
3308     TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST,0,0);
3309     stream1->set_rate(TrexStreamRate::RATE_PPS, 1.0);
3310     stream1->set_single_burst(100);
3311
3312     stream1->m_enabled = true;
3313     stream1->m_self_start = true;
3314     stream1->m_port_id= port_id;
3315
3316
3317     CPcapLoader pcap;
3318     pcap.load_pcap_file("cap2/udp_64B.pcap",0);
3319     pcap.update_ip_src(0x10000001);
3320     pcap.clone_packet_into_stream(stream1);
3321
3322     streams.push_back(stream1);
3323
3324     // stream - clean
3325
3326     std::vector<TrexStreamsCompiledObj *>objs;
3327     assert(compile.compile(port_id, streams, objs));
3328     TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 17, objs[0], 10.0 /*sec */ );
3329
3330
3331     t1.m_msg = lpStartCmd;
3332
3333     /* let me handle these */
3334     DpToCpHandlerStopEvent handler(17);
3335     t1.m_dp_to_cp_handler = &handler;
3336
3337     bool res=t1.init();
3338     EXPECT_EQ_UINT32(1, res?1:0);
3339
3340     delete stream1 ;
3341
3342}
3343
3344TEST_F(basic_stl, graph_generator1) {
3345    std::vector<TrexStream *> streams;
3346    TrexStreamsGraph graph;
3347    TrexStream *stream;
3348
3349     /* stream 1 */
3350     stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 1);
3351     stream->m_enabled = true;
3352     stream->m_self_start = true;
3353
3354     stream->m_isg_usec = 42;
3355     stream->set_rate(TrexStreamRate::RATE_PPS,10);
3356     stream->set_single_burst(43281);
3357     stream->m_pkt.len = 512;
3358
3359     stream->m_next_stream_id = 2;
3360
3361
3362     streams.push_back(stream);
3363
3364     /* stream 2 */
3365     stream = new TrexStream(TrexStream::stMULTI_BURST, 0, 2);
3366     stream->m_enabled = true;
3367     stream->m_self_start = false;
3368
3369     stream->set_rate(TrexStreamRate::RATE_PPS,20);
3370     stream->set_multi_burst(4918, 13, 7);
3371     stream->m_next_stream_id = -1;
3372     stream->m_pkt.len = 64;
3373
3374     streams.push_back(stream);
3375
3376     /* stream 3 */
3377     stream = new TrexStream(TrexStream::stCONTINUOUS, 0, 3);
3378     stream->m_enabled = true;
3379     stream->m_self_start = true;
3380
3381     stream->m_isg_usec = 50;
3382     stream->set_rate(TrexStreamRate::RATE_PPS,30);
3383     stream->m_next_stream_id = -1;
3384     stream->m_pkt.len = 1512;
3385
3386     streams.push_back(stream);
3387
3388
3389     const TrexStreamsGraphObj *obj = graph.generate(streams);
3390     EXPECT_EQ(obj->get_max_bps_l2(), 405120);
3391     EXPECT_EQ(obj->get_max_pps(), 50);
3392
3393     for (auto stream : streams) {
3394         delete stream;
3395     }
3396
3397     delete obj;
3398}
3399
3400
3401TEST_F(basic_stl, graph_generator2) {
3402    std::vector<TrexStream *> streams;
3403    TrexStreamsGraph graph;
3404    TrexStream *stream;
3405
3406    /* add some multi burst streams */
3407    stream = new TrexStream(TrexStream::stMULTI_BURST, 0, 1);
3408    stream->m_enabled = true;
3409    stream->m_self_start = true;
3410
3411
3412    stream->set_rate(TrexStreamRate::RATE_PPS,1000);
3413
3414    /* a burst of 2000 packets with a delay of 1 second */
3415    stream->m_isg_usec = 0;
3416    stream->set_multi_burst(1000, 500, 1000 * 1000);
3417    stream->m_pkt.len = 64;
3418
3419    stream->m_next_stream_id = -1;
3420
3421    streams.push_back(stream);
3422
3423    /* another multi burst stream but with a shorter burst ( less 2 ms ) and
3424       higher ibg (2 ms) , one milli for each side
3425     */
3426    stream = new TrexStream(TrexStream::stMULTI_BURST, 0, 2);
3427    stream->m_enabled = true;
3428    stream->m_self_start = true;
3429
3430    stream->set_rate(TrexStreamRate::RATE_PPS,1000);
3431    stream->m_isg_usec = 1000 * 1000 + 1000;
3432    stream->set_multi_burst(1000 - 2, 1000, 1000 * 1000 + 2000);
3433    stream->m_pkt.len = 128;
3434
3435    stream->m_next_stream_id = -1;
3436
3437    streams.push_back(stream);
3438
3439    const TrexStreamsGraphObj *obj = graph.generate(streams);
3440    EXPECT_EQ(obj->get_max_pps(), 1000.0);
3441
3442    EXPECT_EQ(obj->get_max_bps_l2(), (1000 * (128 + 4) * 8));
3443
3444
3445    for (auto stream : streams) {
3446        delete stream;
3447    }
3448
3449    delete obj;
3450}
3451
3452class VmSplitTest {
3453
3454public:
3455
3456    VmSplitTest(const char *erf_filename) {
3457        m_erf_filename = erf_filename;
3458        m_stream = NULL;
3459
3460        pcap.load_pcap_file("cap2/udp_64B.pcap",0);
3461        pcap.update_ip_src(0x10000001);
3462
3463    }
3464
3465    ~VmSplitTest() {
3466    }
3467
3468    void set_stream(TrexStream *stream) {
3469
3470        if (m_stream) {
3471            delete m_stream;
3472            m_stream = NULL;
3473        }
3474
3475        m_stream = stream;
3476        m_stream->m_enabled = true;
3477        m_stream->m_self_start = true;
3478
3479        pcap.clone_packet_into_stream(stream);
3480    }
3481
3482    void set_flow_var_as_split(StreamVmInstructionFlowMan::flow_var_op_e op,
3483                               uint64_t start,
3484                               uint64_t end,
3485                               uint64_t init) {
3486
3487        assert(m_stream);
3488
3489        StreamVmInstructionVar *split_instr = new StreamVmInstructionFlowMan("var1",
3490                                                                             8,
3491                                                                             op,
3492                                                                             init,
3493                                                                             start,
3494                                                                             end);
3495
3496        StreamVm &vm = m_stream->m_vm;
3497
3498        vm.add_instruction(split_instr);
3499
3500        vm.add_instruction(new StreamVmInstructionWriteToPkt( "var1", 60 - 8 - 4, 0,true));
3501
3502        vm.add_instruction(new StreamVmInstructionFixChecksumIpv4(14));
3503
3504        vm.set_split_instruction(split_instr);
3505
3506    }
3507
3508    void set_client_var_as_split(uint32_t client_min_value,
3509                                 uint32_t client_max_value,
3510                                 uint16_t port_min,
3511                                 uint16_t port_max) {
3512
3513
3514        assert(m_stream);
3515
3516        StreamVmInstructionVar *split_instr = new StreamVmInstructionFlowClient("var1",
3517                                                                                client_min_value,
3518                                                                                client_max_value,
3519                                                                                port_min,
3520                                                                                port_max,
3521                                                                                0,
3522                                                                                0);
3523
3524
3525        StreamVm &vm = m_stream->m_vm;
3526
3527        vm.add_instruction(split_instr);
3528
3529        /* src ip */
3530        vm.add_instruction(new StreamVmInstructionWriteToPkt( "var1.ip",26, 0,true));
3531        vm.add_instruction(new StreamVmInstructionFixChecksumIpv4(14));
3532
3533        /* src port */
3534        vm.add_instruction(new StreamVmInstructionWriteToPkt("var1.port",34, 0,true));
3535
3536        vm.set_split_instruction(split_instr);
3537    }
3538
3539    void run(uint8_t dp_core_count, uint8_t dp_core_to_check) {
3540        TrexStreamsCompiler compile;
3541        std::vector<TrexStreamsCompiledObj *> objs;
3542        std::vector<TrexStream *> streams;
3543
3544        if (m_stream->m_vm.is_vm_empty()) {
3545            set_flow_var_as_split(StreamVmInstructionFlowMan::FLOW_VAR_OP_INC,
3546                                  0,
3547                                  1000,
3548                                  0);
3549        }
3550
3551        streams.push_back(m_stream);
3552
3553        /* compiling for 8 cores */
3554        assert(compile.compile(0, streams, objs, dp_core_count));
3555
3556        /* choose one DP object */
3557        assert(objs[dp_core_to_check]);
3558
3559        TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(0, 0, objs[dp_core_to_check], 1 /*sec */ );
3560        objs[dp_core_to_check] = NULL;
3561        /* free all the non used DP objects */
3562        for (auto obj : objs) {
3563            if (obj) {
3564                delete obj;
3565            }
3566        }
3567
3568
3569        CParserOption * po =&CGlobalInfo::m_options;
3570        po->preview.setVMode(7);
3571        po->preview.setFileWrite(true);
3572        po->out_file = m_erf_filename;
3573
3574        CBasicStl t1;
3575        t1.m_msg = lpStartCmd;
3576        bool res=t1.init();
3577        EXPECT_EQ_UINT32(1, res?1:0);
3578
3579    }
3580
3581private:
3582    const char *m_erf_filename;
3583    TrexStream *m_stream;
3584    CPcapLoader pcap;
3585};
3586
3587
3588
3589TEST_F(basic_stl, vm_split_flow_var_inc) {
3590
3591    VmSplitTest split("exp/stl_vm_split_flow_var_inc.erf");
3592
3593    TrexStream stream(TrexStream::stSINGLE_BURST, 0, 0);
3594    stream.set_single_burst(1000);
3595    stream.set_rate(TrexStreamRate::RATE_PPS,100000);
3596
3597    split.set_stream(&stream);
3598    split.run(8, 4);
3599
3600}
3601
3602TEST_F(basic_stl, vm_split_flow_var_small_range) {
3603    /* small range */
3604    VmSplitTest split("exp/stl_vm_split_flow_var_small_range.erf");
3605
3606    TrexStream stream(TrexStream::stSINGLE_BURST, 0, 0);
3607    stream.set_single_burst(1000);
3608    stream.set_rate(TrexStreamRate::RATE_PPS,100000);
3609
3610    split.set_stream(&stream);
3611    split.set_flow_var_as_split(StreamVmInstructionFlowMan::FLOW_VAR_OP_INC, 0, 1, 0);
3612
3613    split.run(8, 4);
3614
3615}
3616
3617TEST_F(basic_stl, vm_split_flow_var_big_range) {
3618    VmSplitTest split("exp/stl_vm_split_flow_var_big_range.erf");
3619
3620    TrexStream stream(TrexStream::stSINGLE_BURST, 0, 0);
3621    stream.set_single_burst(1000);
3622    stream.set_rate(TrexStreamRate::RATE_PPS,100000);
3623
3624    split.set_stream(&stream);
3625    split.set_flow_var_as_split(StreamVmInstructionFlowMan::FLOW_VAR_OP_DEC, 1, 1000, 1000);
3626
3627    split.run(8, 7);
3628
3629
3630}
3631
3632TEST_F(basic_stl, vm_split_client_var) {
3633     VmSplitTest split("exp/stl_vm_split_client_var.erf");
3634
3635    TrexStream stream(TrexStream::stSINGLE_BURST, 0, 0);
3636    stream.set_single_burst(1000);
3637    stream.set_rate(TrexStreamRate::RATE_PPS,100000);
3638
3639    split.set_stream(&stream);
3640    split.set_client_var_as_split(0x10000001, 0x100000fe, 5000, 5050);
3641
3642    split.run(8, 7);
3643
3644
3645}
3646
3647TEST_F(basic_stl, pcap_remote_basic) {
3648
3649    CBasicStl t1;
3650    CParserOption * po =&CGlobalInfo::m_options;
3651    po->preview.setVMode(7);
3652    po->preview.setFileWrite(true);
3653    po->out_file ="exp/pcap_remote_basic";
3654
3655    TrexStatelessCpToDpMsgBase *push_msg = new TrexStatelessDpPushPCAP(0,
3656                                                                       0,
3657                                                                       "exp/remote_test.cap",
3658                                                                       10,
3659                                                                       1,
3660                                                                       1,
3661                                                                       -1,
3662                                                                       false);
3663    t1.m_msg = push_msg;
3664
3665
3666    bool res = t1.init();
3667    EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
3668}
3669
3670TEST_F(basic_stl, pcap_remote_loop) {
3671
3672    CBasicStl t1;
3673    CParserOption * po =&CGlobalInfo::m_options;
3674    po->preview.setVMode(7);
3675    po->preview.setFileWrite(true);
3676    po->out_file ="exp/pcap_remote_loop";
3677
3678    TrexStatelessCpToDpMsgBase *push_msg = new TrexStatelessDpPushPCAP(0,
3679                                                                       0,
3680                                                                       "exp/remote_test.cap",
3681                                                                       1,
3682                                                                       1,
3683                                                                       3,
3684                                                                       -1,
3685                                                                       false);
3686    t1.m_msg = push_msg;
3687
3688    bool res = t1.init();
3689    EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
3690}
3691
3692TEST_F(basic_stl, pcap_remote_duration) {
3693
3694    CBasicStl t1;
3695    CParserOption * po =&CGlobalInfo::m_options;
3696    po->preview.setVMode(7);
3697    po->preview.setFileWrite(true);
3698    po->out_file ="exp/pcap_remote_duration";
3699
3700    TrexStatelessCpToDpMsgBase *push_msg = new TrexStatelessDpPushPCAP(0,
3701                                                                       0,
3702                                                                       "exp/remote_test.cap",
3703                                                                       100000,
3704                                                                       1,
3705                                                                       0,
3706                                                                       0.5,
3707                                                                       false);
3708    t1.m_msg = push_msg;
3709
3710    bool res = t1.init();
3711    EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
3712}
3713
3714TEST_F(basic_stl, pcap_remote_dual) {
3715
3716    CBasicStl t1;
3717    CParserOption * po =&CGlobalInfo::m_options;
3718    po->preview.setVMode(7);
3719    po->preview.setFileWrite(true);
3720    po->out_file ="exp/pcap_remote_dual";
3721
3722    TrexStatelessCpToDpMsgBase *push_msg = new TrexStatelessDpPushPCAP(0,
3723                                                                       0,
3724                                                                       "exp/remote_test_dual.erf",
3725                                                                       10000,
3726                                                                       1,
3727                                                                       0,
3728                                                                       0.5,
3729                                                                       true);
3730    t1.m_msg = push_msg;
3731
3732    bool res = t1.init();
3733    EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
3734}
3735
3736/********************************************* Itay Tests End *************************************/
3737class flow_stat_pkt_parse  : public testing::Test {
3738    protected:
3739     virtual void SetUp() {
3740     }
3741     virtual void TearDown() {
3742     }
3743   public:
3744};
3745
3746
3747TEST_F(flow_stat_pkt_parse, parser) {
3748    CFlowStatParserTest parser;
3749
3750    parser.test();
3751}
3752
3753class flow_stat  : public testing::Test {
3754    protected:
3755     virtual void SetUp() {
3756     }
3757     virtual void TearDown() {
3758     }
3759   public:
3760};
3761
3762
3763static const uint8_t TEST_L4_PROTO = IPPROTO_TCP;
3764
3765TEST_F(flow_stat, add_del_stream) {
3766    CFlowStatRuleMgr rule_mgr;
3767    uint8_t test_pkt[] = {
3768        // ether header
3769        0x74, 0xa2, 0xe6, 0xd5, 0x39, 0x25,
3770        0xa0, 0x36, 0x9f, 0x38, 0xa4, 0x02,
3771        0x81, 0x00,
3772        0x0a, 0xbc, 0x08, 0x00, // vlan
3773        // IP header
3774        0x45,0x02,0x00,0x30,
3775        0x01,0x02,0x40,0x00,
3776        0xff, TEST_L4_PROTO, 0xbd,0x04,
3777        0x10,0x0,0x0,0x1,
3778        0x30,0x0,0x0,0x1,
3779        // TCP heaader
3780        0xab, 0xcd, 0x00, 0x80, // src, dst ports
3781        0x01, 0x02, 0x03, 0x04, 0x05, 0x06, 0x07, 0x08, // seq num, ack num
3782        0x50, 0x00, 0xff, 0xff, // Header size, flags, window size
3783        0x00, 0x00, 0x00, 0x00, // checksum ,urgent pointer
3784        // some extra bytes
3785        0x1, 0x2, 0x3, 0x4
3786    };
3787
3788    TrexStream stream(TrexStream::stSINGLE_BURST, 0, 0);
3789    TrexStream stream2(TrexStream::stSINGLE_BURST, 0, 0);
3790    TrexStream stream3(TrexStream::stSINGLE_BURST, 0, 0);
3791
3792    stream.m_rx_check.m_enabled = true;
3793
3794    stream.m_rx_check.m_rule_type = 7;
3795    stream.m_rx_check.m_pg_id = 5;
3796    stream.m_pkt.binary = (uint8_t *)test_pkt;
3797    stream.m_pkt.len = sizeof(test_pkt);
3798
3799    rule_mgr.init_stream(&stream);
3800
3801    try {
3802        rule_mgr.del_stream(&stream);
3803    } catch (TrexFStatEx e) {
3804        assert(e.type() == TrexException::T_FLOW_STAT_NO_STREAMS_EXIST);
3805    }
3806
3807    try {
3808        rule_mgr.add_stream(&stream);
3809    } catch (TrexFStatEx e) {
3810        assert(e.type() == TrexException::T_FLOW_STAT_BAD_RULE_TYPE);
3811    }
3812
3813    stream.m_rx_check.m_rule_type = TrexPlatformApi::IF_STAT_PAYLOAD;
3814    try {
3815        rule_mgr.add_stream(&stream);
3816    } catch (TrexFStatEx e) {
3817        assert(e.type() == TrexException::T_FLOW_STAT_PAYLOAD_TOO_SHORT);
3818    }
3819
3820    // change to UDP packet so it will be fine to work with
3821    test_pkt[27] = IPPROTO_UDP;
3822    int ret = rule_mgr.add_stream(&stream);
3823    assert (ret == 0);
3824
3825    stream3.m_rx_check.m_enabled = true;
3826    stream3.m_rx_check.m_rule_type = TrexPlatformApi::IF_STAT_PAYLOAD;
3827    stream3.m_rx_check.m_pg_id = 5; // same as first stream
3828    stream3.m_pkt.binary = (uint8_t *)test_pkt;
3829    stream3.m_pkt.len = sizeof(test_pkt);
3830    try {
3831        ret = rule_mgr.add_stream(&stream3);
3832    } catch (TrexFStatEx e) {
3833        assert(e.type() == TrexException::T_FLOW_STAT_DUP_PG_ID);
3834    }
3835
3836    ret = rule_mgr.del_stream(&stream);
3837    assert (ret == 0);
3838
3839    stream2.m_rx_check.m_enabled = true;
3840    stream2.m_rx_check.m_rule_type = TrexPlatformApi::IF_STAT_IPV4_ID;
3841    stream2.m_rx_check.m_pg_id = 5; // same as first stream
3842    stream2.m_pkt.binary = (uint8_t *)test_pkt;
3843    stream2.m_pkt.len = sizeof(test_pkt);
3844    ret = rule_mgr.add_stream(&stream2);
3845    assert (ret == 0);
3846
3847    ret = rule_mgr.del_stream(&stream2);
3848    assert (ret == 0);
3849    try {
3850        rule_mgr.del_stream(&stream2);
3851    } catch (TrexFStatEx e) {
3852        assert(e.type() == TrexException::T_FLOW_STAT_DEL_NON_EXIST);
3853    }
3854
3855    // do not want the destructor to try to free it
3856    stream.m_pkt.binary = NULL;
3857    stream2.m_pkt.binary = NULL;
3858    stream3.m_pkt.binary = NULL;
3859}
3860
3861TEST_F(flow_stat, alloc_mbuf_const) {
3862     CGenNodeStateless cg;
3863
3864     cg.alloc_flow_stat_mbuf_test_const();
3865}
3866