bp_gtest.cpp revision e9b4c74d
1/*
2 Hanoh 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 <common/gtest.h>
24#include <common/basic_utils.h>
25#include "utl_cpuu.h"
26#include "timer_wheel_pq.h"
27#include "rx_check.h"
28#include "time_histogram.h"
29#include "utl_jitter.h"
30#include "CRing.h"
31#include "msg_manager.h"
32#include <common/cgen_map.h>
33#include "platform_cfg.h"
34#include "stateful_rx_core.h"
35#include "nat_check_flow_table.h"
36
37int test_policer(){
38    CPolicer policer;
39
40    policer.set_cir( 100.0);
41    policer.set_level(0.0);
42    policer.set_bucket_size(100.0);
43
44    double t;
45    uint32_t c=0;
46    for (t=0.001;t<10.0; t=t+0.001) {
47        if ( policer.update(1.0,t) ){
48            c++;
49            printf(" %f \n",t);
50        }
51    }
52    printf(" %u \n",c);
53    if ( ( c > 970.0) &&  ( c < 1000.0) ) {
54        printf(" ok \n");
55        return (0);
56    }else{
57        printf("error \n");
58        return (-1);
59    }
60}
61
62
63
64
65int test_priorty_queue(void){
66    CGenNode * node;
67    std::priority_queue<CGenNode *, std::vector<CGenNode *>,CGenNodeCompare> p_queue;
68    int i;
69    for (i=0; i<10; i++) {
70         node = new CGenNode();
71         printf(" +%p \n",node);
72         node->m_flow_id = 10-i;
73         node->m_pkt_info = (CFlowPktInfo *)(uintptr_t)i;
74         node->m_time = (double)i+0.1;
75         p_queue.push(node);
76    }
77    while (!p_queue.empty()) {
78        node = p_queue.top();
79        printf(" -->%p \n",node);
80        //node->Dump(stdout);
81        p_queue.pop();
82        //delete node;
83    }
84    return (0);
85}
86
87
88#if 0
89#ifdef WIN32
90
91int test_rate(){
92    int i;
93    CBwMeasure m;
94    uint64_t cnt=0;
95    for (i=0; i<10; i++) {
96        Sleep(100);
97        cnt+=10000;
98        printf (" %f \n",m.add(cnt));
99    }
100    return (0);
101}
102#endif
103#endif
104
105
106
107
108void histogram_test(){
109    CTimeHistogram t;
110    t.Create();
111    t.Add(0.0001);
112    t.Add(0.0002);
113    t.Add(0.0003);
114    int i;
115    for (i=0; i<100;i++) {
116        t.Add(1.0/1000000.0);
117    }
118    t.Dump(stdout);
119    t.Delete();
120}
121
122
123
124
125int test_human_p(){
126    printf ("%s \n",double_to_human_str(1024.0*1024.0,"Byte",KBYE_1024).c_str());
127    printf ("%s \n",double_to_human_str(1.0,"Byte",KBYE_1024).c_str());
128    printf ("%s \n",double_to_human_str(-3000.0,"Byte",KBYE_1024).c_str());
129    printf ("%s \n",double_to_human_str(-3000000.0,"Byte",KBYE_1024).c_str());
130    printf ("%s \n",double_to_human_str(-30000000.0,"Byte",KBYE_1024).c_str());
131    return (0);
132}
133
134
135
136
137
138
139#define EXPECT_EQ_UINT32(a,b) EXPECT_EQ((uint32_t)(a),(uint32_t)(b))
140
141
142class CTestBasic {
143
144public:
145    CTestBasic(){
146        m_threads=1;
147        m_time_diff=0.001;
148        m_req_ports=0;
149        m_dump_json=false;
150    }
151
152    bool  init(void){
153
154        uint16 * ports = NULL;
155        CTupleBase tuple;
156
157        CErfIF erf_vif;
158
159
160        fl.Create();
161        m_saved_packet_padd_offset=0;
162
163        fl.load_from_yaml(CGlobalInfo::m_options.cfg_file,m_threads);
164        fl.generate_p_thread_info(m_threads);
165
166        CFlowGenListPerThread   * lpt;
167
168        fl.m_threads_info[0]->set_vif(&erf_vif);
169
170
171        CErfCmp cmp;
172        cmp.dump=1;
173
174        bool res=true;
175
176
177        int i;
178        for (i=0; i<m_threads; i++) {
179            lpt=fl.m_threads_info[i];
180
181            CFlowPktInfo *  pkt=lpt->m_cap_gen[0]->m_flow_info->GetPacket(0);
182            m_saved_packet_padd_offset =pkt->m_pkt_indication.m_packet_padding;
183
184            char buf[100];
185            char buf_ex[100];
186            sprintf(buf,"%s-%d.erf",CGlobalInfo::m_options.out_file.c_str(),i);
187            sprintf(buf_ex,"%s-%d-ex.erf",CGlobalInfo::m_options.out_file.c_str(),i);
188
189            if ( m_req_ports ){
190                /* generate from first template m_req_ports ports */
191                int i;
192                CTupleTemplateGeneratorSmart * lpg=&lpt->m_cap_gen[0]->tuple_gen;
193                ports = new uint16_t[m_req_ports];
194                lpg->GenerateTuple(tuple);
195                for (i=0 ; i<m_req_ports;i++) {
196                    ports[i]=lpg->GenerateOneSourcePort();
197                }
198            }
199            CGlobalInfo::m_options.m_run_mode = CParserOption::RUN_MODE_BATCH;
200            lpt->start_generate_stateful(buf,CGlobalInfo::m_options.preview);
201            lpt->m_node_gen.DumpHist(stdout);
202
203            cmp.d_sec = m_time_diff;
204            //compare
205            if ( cmp.compare(std::string(buf),std::string(buf_ex)) != true ) {
206                res=false;
207            }
208
209        }
210        if ( m_dump_json ){
211            printf(" dump json ...........\n");
212            std::string s;
213            fl.m_threads_info[0]->m_node_gen.dump_json(s);
214            printf(" %s \n",s.c_str());
215        }
216
217        if ( m_req_ports ){
218            int i;
219            fl.m_threads_info[0]->m_smart_gen.FreePort(0, tuple.getClientId(),tuple.getClientPort());
220
221            for (i=0 ; i<m_req_ports;i++) {
222                fl.m_threads_info[0]->m_smart_gen.FreePort(0,tuple.getClientId(),ports[i]);
223            }
224            delete []ports;
225        }
226
227        printf(" active %d \n", fl.m_threads_info[0]->m_smart_gen.ActiveSockets());
228        EXPECT_EQ_UINT32(fl.m_threads_info[0]->m_smart_gen.ActiveSockets(),0);
229        fl.Delete();
230        return (res);
231    }
232
233    uint16_t  get_padd_offset_first_packet(){
234        return (m_saved_packet_padd_offset);
235
236    }
237
238
239
240public:
241    int           m_req_ports;
242    int           m_threads;
243    double        m_time_diff;
244    bool          m_dump_json;
245    uint16_t      m_saved_packet_padd_offset;
246    CFlowGenList  fl;
247};
248
249
250
251
252class basic  : public testing::Test {
253 protected:
254  virtual void SetUp() {
255  }
256  virtual void TearDown() {
257  }
258public:
259};
260
261class cpu  : public testing::Test {
262 protected:
263  virtual void SetUp() {
264  }
265  virtual void TearDown() {
266  }
267public:
268};
269
270
271
272TEST_F(basic, limit_single_pkt) {
273
274     CTestBasic t1;
275     CParserOption * po =&CGlobalInfo::m_options;
276     po->preview.setVMode(3);
277     po->preview.setFileWrite(true);
278     po->cfg_file ="cap2/limit_single_pkt.yaml";
279     po->out_file ="exp/limit_single_pkt";
280     bool res=t1.init();
281     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
282}
283
284TEST_F(basic, limit_multi_pkt) {
285
286     CTestBasic t1;
287     CParserOption * po =&CGlobalInfo::m_options;
288     po->preview.setVMode(3);
289     po->preview.setFileWrite(true);
290     po->cfg_file ="cap2/limit_multi_pkt.yaml";
291     po->out_file ="exp/limit_multi_pkt";
292     bool res=t1.init();
293     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
294}
295
296TEST_F(basic, imix) {
297
298     CTestBasic t1;
299     CParserOption * po =&CGlobalInfo::m_options;
300     po->preview.setVMode(3);
301     po->preview.setFileWrite(true);
302     po->cfg_file ="cap2/imix.yaml";
303     po->out_file ="exp/imix";
304     bool res=t1.init();
305     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
306}
307
308
309TEST_F(basic, dns) {
310
311     CTestBasic t1;
312     CParserOption * po =&CGlobalInfo::m_options;
313     po->preview.setVMode(3);
314     po->preview.setFileWrite(true);
315     po->cfg_file ="cap2/dns.yaml";
316     po->out_file ="exp/dns";
317     bool res=t1.init();
318     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
319}
320
321/* test -p function */
322TEST_F(basic, dns_flow_flip) {
323
324     CTestBasic t1;
325     CParserOption * po =&CGlobalInfo::m_options;
326     po->preview.setVMode(3);
327     po->preview.setFileWrite(true);
328     po->preview.setClientServerFlowFlip(true);
329
330     po->cfg_file ="cap2/dns.yaml";
331     po->out_file ="exp/dns_p";
332     bool res=t1.init();
333     po->preview.setClientServerFlowFlip(false);
334
335     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
336}
337
338TEST_F(basic, dns_flip) {
339
340     CTestBasic t1;
341     CParserOption * po =&CGlobalInfo::m_options;
342     po->preview.setVMode(3);
343     po->preview.setFileWrite(true);
344     po->preview.setClientServerFlip(true);
345
346     po->cfg_file ="cap2/dns.yaml";
347     po->out_file ="exp/dns_flip";
348     bool res=t1.init();
349     po->preview.setClientServerFlip(false);
350
351     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
352}
353
354TEST_F(basic, dns_e) {
355
356     CTestBasic t1;
357     CParserOption * po =&CGlobalInfo::m_options;
358     po->preview.setVMode(3);
359     po->preview.setFileWrite(true);
360     po->preview.setClientServerFlowFlipAddr(true);
361
362     po->cfg_file ="cap2/dns.yaml";
363     po->out_file ="exp/dns_e";
364     bool res=t1.init();
365     po->preview.setClientServerFlowFlipAddr(false);
366
367     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
368}
369
370
371
372/* test the packet padding , must be valid for --rx-check to work */
373TEST_F(basic, dns_packet_padding_test) {
374
375     CTestBasic t1;
376     CParserOption * po =&CGlobalInfo::m_options;
377     po->preview.setVMode(3);
378     po->preview.setFileWrite(true);
379     po->cfg_file ="cap2/dns.yaml";
380     po->out_file ="exp/dns";
381     bool res=t1.init();
382     EXPECT_EQ_UINT32(t1.get_padd_offset_first_packet(),0);
383     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
384}
385
386
387TEST_F(basic, dns_ipv6) {
388
389     CTestBasic t1;
390     CParserOption * po =&CGlobalInfo::m_options;
391     po->preview.setVMode(3);
392     po->preview.setFileWrite(true);
393     po->preview.set_ipv6_mode_enable(true);
394     po->cfg_file ="cap2/dns.yaml";
395     po->out_file ="exp/dns_ipv6";
396     bool res=t1.init();
397     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
398     EXPECT_EQ_UINT32(t1.get_padd_offset_first_packet(),0);
399     po->preview.set_ipv6_mode_enable(false);
400}
401
402TEST_F(basic, dns_json) {
403     CTestBasic t1;
404     CParserOption * po =&CGlobalInfo::m_options;
405     t1.m_dump_json=true;
406     po->preview.setVMode(3);
407     po->preview.setFileWrite(true);
408     po->cfg_file ="cap2/dns.yaml";
409     po->out_file ="exp/dns";
410     bool res=t1.init();
411     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
412}
413
414
415#if 0
416
417TEST_F(basic, dns_wlen) {
418
419     CTestBasic t1;
420     CParserOption * po =&CGlobalInfo::m_options;
421     po->preview.setVMode(3);
422     po->preview.setFileWrite(true);
423     po->cfg_file ="cap2/dns_wlen.yaml";
424     po->out_file ="exp/dns_wlen";
425     bool res=t1.init();
426     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
427}
428
429TEST_F(basic, dns_wlen1) {
430
431     CTestBasic t1;
432     CParserOption * po =&CGlobalInfo::m_options;
433     po->preview.setVMode(3);
434     po->preview.setFileWrite(true);
435     po->cfg_file ="cap2/dns_wlen1.yaml";
436     po->out_file ="exp/dns_wlen1";
437     bool res=t1.init();
438     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
439}
440
441TEST_F(basic, dns_wlen2) {
442
443     CTestBasic t1;
444     CParserOption * po =&CGlobalInfo::m_options;
445     po->preview.setVMode(3);
446     po->preview.setFileWrite(true);
447     po->cfg_file ="cap2/dns_wlen2.yaml";
448     po->out_file ="exp/dns_wlen2";
449     bool res=t1.init();
450     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
451}
452
453
454
455TEST_F(basic, dns_one_server_2) {
456
457     CTestBasic t1;
458     CParserOption * po =&CGlobalInfo::m_options;
459     po->preview.setVMode(3);
460     po->preview.setFileWrite(true);
461     po->cfg_file ="cap2/dns_single_server.yaml";
462     po->out_file ="exp/dns_single_server";
463     bool res=t1.init();
464     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
465}
466
467#endif
468
469TEST_F(basic, dns_one_server) {
470
471     CTestBasic t1;
472     CParserOption * po =&CGlobalInfo::m_options;
473     po->preview.setVMode(3);
474     po->preview.setFileWrite(true);
475     po->cfg_file ="cap2/dns_one_server.yaml";
476     po->out_file ="exp/dns_one_server";
477     bool res=t1.init();
478     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
479}
480
481
482TEST_F(basic, sfr2) {
483
484     CTestBasic t1;
485     CParserOption * po =&CGlobalInfo::m_options;
486
487     po->preview.setVMode(0);
488     po->preview.setFileWrite(true);
489     po->cfg_file ="cap2/sfr2.yaml";
490     po->out_file ="exp/sfr2";
491     bool res=t1.init();
492     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
493}
494
495
496TEST_F(basic, sfr3) {
497
498     CTestBasic t1;
499     CParserOption * po =&CGlobalInfo::m_options;
500     po->preview.setVMode(0);
501     po->preview.setFileWrite(true);
502     po->cfg_file ="cap2/sfr3.yaml";
503     po->out_file ="exp/sfr3";
504     bool res=t1.init();
505     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
506}
507
508
509TEST_F(basic, sfr4) {
510
511     CTestBasic t1;
512     CParserOption * po =&CGlobalInfo::m_options;
513     po->preview.setVMode(0);
514     po->preview.setFileWrite(true);
515     po->cfg_file ="cap2/sfr4.yaml";
516     po->out_file ="exp/sfr_4";
517     bool res=t1.init();
518     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
519}
520
521TEST_F(basic, per_template_gen1) {
522
523     CTestBasic t1;
524     CParserOption * po =&CGlobalInfo::m_options;
525     po->preview.setVMode(0);
526     po->preview.setFileWrite(true);
527     po->cfg_file ="cap2/per_template_gen1.yaml";
528     po->out_file ="exp/sfr_4";
529     bool res=t1.init();
530     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
531}
532TEST_F(basic, per_template_gen2) {
533
534     CTestBasic t1;
535     CParserOption * po =&CGlobalInfo::m_options;
536     po->preview.setVMode(0);
537     po->preview.setFileWrite(true);
538     po->cfg_file ="cap2/per_template_gen2.yaml";
539     po->out_file ="exp/sfr_4";
540     bool res=t1.init();
541     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
542}
543
544
545/*
546TEST_F(basic, sfr5) {
547
548     CTestBasic t1;
549     CParserOption * po =&CGlobalInfo::m_options;
550     po->preview.setVMode(0);
551     po->preview.setFileWrite(true);
552     po->cfg_file ="cap2/sfr5.yaml";
553     po->out_file ="exp/sfr_5";
554     bool res=t1.init();
555     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
556}
557*/
558
559
560TEST_F(basic, ipv6_convert) {
561
562     CTestBasic t1;
563     CParserOption * po =&CGlobalInfo::m_options;
564     po->preview.setVMode(3);
565     po->preview.set_ipv6_mode_enable(true);
566     po->preview.setFileWrite(true);
567     po->cfg_file ="cap2/imix.yaml";
568     po->out_file ="exp/imix_v6";
569     bool res=t1.init();
570     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
571     po->preview.set_ipv6_mode_enable(false);
572}
573
574TEST_F(basic, ipv6) {
575
576     CTestBasic t1;
577     CParserOption * po =&CGlobalInfo::m_options;
578     po->preview.setVMode(3);
579     po->preview.set_ipv6_mode_enable(true);
580     po->preview.setFileWrite(true);
581     po->cfg_file ="cap2/ipv6.yaml";
582     po->out_file ="exp/ipv6";
583     bool res=t1.init();
584     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
585     po->preview.set_ipv6_mode_enable(false);
586}
587
588TEST_F(basic, ipv4_vlan) {
589
590     CTestBasic t1;
591     CParserOption * po =&CGlobalInfo::m_options;
592     po->preview.setVMode(3);
593     po->preview.setFileWrite(true);
594     po->cfg_file ="cap2/ipv4_vlan.yaml";
595     po->out_file ="exp/ipv4_vlan";
596     bool res=t1.init();
597     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
598}
599
600TEST_F(basic, ipv6_vlan) {
601
602     CTestBasic t1;
603     CParserOption * po =&CGlobalInfo::m_options;
604     po->preview.setVMode(3);
605     po->preview.set_ipv6_mode_enable(true);
606     po->preview.setFileWrite(true);
607     po->cfg_file ="cap2/ipv6_vlan.yaml";
608     po->out_file ="exp/ipv6_vlan";
609     bool res=t1.init();
610     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
611     po->preview.set_ipv6_mode_enable(false);
612}
613
614
615/* exacly like cap file */
616TEST_F(basic, test_pcap_mode1) {
617
618     CTestBasic t1;
619     CParserOption * po =&CGlobalInfo::m_options;
620     po->preview.setVMode(3);
621     po->preview.setFileWrite(true);
622     po->cfg_file ="cap2/test_pcap_mode1.yaml";
623     po->out_file ="exp/pcap_mode1";
624     t1.m_time_diff = 0.000005; // 5 nsec
625     bool res=t1.init();
626     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
627}
628
629/* check override the low IPG */
630TEST_F(basic, test_pcap_mode2) {
631
632     CTestBasic t1;
633     CParserOption * po =&CGlobalInfo::m_options;
634     po->preview.setVMode(3);
635     po->preview.setFileWrite(true);
636     po->cfg_file ="cap2/test_pcap_mode2.yaml";
637     po->out_file ="exp/pcap_mode2";
638     t1.m_time_diff = 0.000005; // 5 nsec
639     bool res=t1.init();
640     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
641}
642
643#define l_pkt_test_s_ip 0x01020304
644#define l_pkt_test_d_ip 0x05060708
645
646CLatencyPktMode *
647latency_pkt_mod_create(uint8_t l_pkt_mode) {
648    switch (l_pkt_mode) {
649    default:
650        return  new CLatencyPktModeSCTP(l_pkt_mode);
651        break;
652    case L_PKT_SUBMODE_NO_REPLY:
653    case L_PKT_SUBMODE_REPLY:
654    case L_PKT_SUBMODE_0_SEQ:
655        return new CLatencyPktModeICMP(l_pkt_mode);
656        break;
657    }
658}
659
660rte_mbuf_t *
661create_latency_test_pkt(uint8_t l_pkt_mode, uint16_t &pkt_size, uint8_t port_id, uint8_t pkt_num) {
662    rte_mbuf_t * m;
663    CLatencyPktMode *c_l_pkt_mode;
664    CCPortLatency port0;
665    CLatencyPktInfo info;
666    CLatencyManager mgr;
667
668    c_l_pkt_mode = latency_pkt_mod_create(l_pkt_mode);
669
670    mgr.c_l_pkt_mode = c_l_pkt_mode;
671    info.Create(c_l_pkt_mode);
672    port0.Create(&mgr, 0, info.get_payload_offset(), info.get_l4_offset(), info.get_pkt_size(), 0);
673    info.set_ip(l_pkt_test_s_ip ,l_pkt_test_d_ip, 0x01000000);
674    m=info.generate_pkt(0);
675    while (pkt_num > 0) {
676        pkt_num--;
677        port0.update_packet(m, port_id);
678    }
679    pkt_size = info.get_pkt_size();
680    port0.Delete();
681    info.Delete();
682    delete c_l_pkt_mode;
683
684    return m;
685}
686
687bool
688verify_latency_pkt(uint8_t *p, uint8_t proto, uint16_t icmp_seq, uint8_t icmp_type) {
689    EthernetHeader *eth = (EthernetHeader *)p;
690    IPHeader *ip = (IPHeader *)(p + 14);
691    uint8_t  srcmac[]={0x10,0x10,0x10,0x10,0x10,0x10};
692    //uint8_t  dstmac[]={0x0,0x0,0x0,0x0,0x0,0x0};
693    latency_header * h;
694
695    // eth
696    EXPECT_EQ_UINT32(eth->getNextProtocol(), 0x0800)<< "Failed ethernet next protocol check";
697    EXPECT_EQ_UINT32(memcmp(p, srcmac, 6), 0)<<  "Failed ethernet source MAC check";
698    //EXPECT_EQ_UINT32(memcmp(p, dstmac, 6), 0)<<  "Failed ethernet dest MAC check";
699    // IP
700    EXPECT_EQ_UINT32(ip->getSourceIp(), l_pkt_test_s_ip)<<  "Failed IP src check";
701    EXPECT_EQ_UINT32(ip->getDestIp(), l_pkt_test_d_ip)<<  "Failed IP dst check";
702    EXPECT_EQ_UINT32(ip->getProtocol(), proto)<<  "Failed IP protocol check";
703    EXPECT_EQ_UINT32(ip->isChecksumOK()?0:1, 0)<<  "Failed IP checksum check";
704    EXPECT_EQ_UINT32(ip->getTimeToLive(), 0xff)<<  "Failed IP ttl check";
705    EXPECT_EQ_UINT32(ip->getTotalLength(), 48)<<  "Failed IP total length check";
706
707    // payload
708    h=(latency_header *)(p+42);
709    EXPECT_EQ_UINT32(h->magic, LATENCY_MAGIC)<<  "Failed latency magic check";
710
711    if (proto == 0x84)
712        return true;
713    // ICMP
714    ICMPHeader *icmp = (ICMPHeader *)(p + 34);
715    EXPECT_EQ_UINT32(icmp->isCheckSumOk(28)?0:1, 0)<<  "Failed ICMP checksum verification";
716    EXPECT_EQ_UINT32(icmp->getSeqNum(), icmp_seq)<< "Failed ICMP sequence number check";
717    EXPECT_EQ_UINT32(icmp->getType(), icmp_type)<<  "Failed ICMP type check";
718    EXPECT_EQ_UINT32(icmp->getCode(), 0)<<  "Failed ICMP code check";
719    EXPECT_EQ_UINT32(icmp->getId(), 0xaabb)<<  "Failed ICMP ID check";
720
721    return true;
722}
723
724bool
725test_latency_pkt_rcv(rte_mbuf_t *m, uint8_t l_pkt_mode, uint8_t port_num, uint16_t num_pkt, bool exp_pkt_ok
726                     , uint16_t exp_tx_seq, uint16_t exp_rx_seq) {
727    CLatencyPktMode *c_l_pkt_mode;
728    CCPortLatency port;
729    CLatencyPktInfo info;
730    CLatencyManager mgr;
731    CRx_check_header *rxc;
732    CGlobalInfo::m_options.m_l_pkt_mode = l_pkt_mode;
733
734    c_l_pkt_mode = latency_pkt_mod_create(l_pkt_mode);
735    mgr.c_l_pkt_mode = c_l_pkt_mode;
736    info.Create(c_l_pkt_mode);
737    port.Create(&mgr, 0, info.get_payload_offset(), info.get_l4_offset(), info.get_pkt_size(), 0);
738    bool pkt_ok = port.check_packet(m, rxc);
739
740    while (num_pkt > 0) {
741        num_pkt--;
742        if (port.can_send_packet(port_num)) {
743            port.update_packet(m, 0);
744        }
745    }
746
747    EXPECT_EQ_UINT32(pkt_ok ?0:1, exp_pkt_ok?0:1)<<  "Failed packet OK check";
748    EXPECT_EQ_UINT32(port.get_icmp_tx_seq(), exp_tx_seq)<<  "Failed tx check";
749    EXPECT_EQ_UINT32(port.get_icmp_rx_seq(), exp_rx_seq)<<  "Failed rx check";
750    // if packet is bad, check_packet raise the error counter
751    EXPECT_EQ_UINT32(port.m_unsup_prot, exp_pkt_ok?0:1)<<  "Failed unsupported packets count";
752
753    return true;
754}
755
756
757// Testing latency packet generation
758TEST_F(basic, latency1) {
759    uint8_t *p;
760    rte_mbuf_t * m;
761    uint16_t pkt_size;
762
763    // SCTP packet
764    m = create_latency_test_pkt(0, pkt_size, 0, 1);
765    p=rte_pktmbuf_mtod(m, uint8_t*);
766    verify_latency_pkt(p, 0x84, 0, 0);
767    rte_pktmbuf_free(m);
768
769    m = create_latency_test_pkt(L_PKT_SUBMODE_NO_REPLY, pkt_size, 1, 2);
770    p=rte_pktmbuf_mtod(m, uint8_t*);
771    verify_latency_pkt(p, 0x01, 2, 8);
772    rte_pktmbuf_free(m);
773
774    // ICMP reply mode client side
775    m = create_latency_test_pkt(L_PKT_SUBMODE_REPLY, pkt_size, 0, 3);
776    p = rte_pktmbuf_mtod(m, uint8_t*);
777    verify_latency_pkt(p, 0x01, 3, 8);
778    rte_pktmbuf_free(m);
779
780    // ICMP reply mode server side
781    m = create_latency_test_pkt(L_PKT_SUBMODE_REPLY, pkt_size, 1, 4);
782    p=rte_pktmbuf_mtod(m, uint8_t*);
783    verify_latency_pkt(p, 0x01, 4, 0);
784    rte_pktmbuf_free(m);
785
786    m = create_latency_test_pkt(L_PKT_SUBMODE_0_SEQ, pkt_size, 1, 5);
787    p=rte_pktmbuf_mtod(m, uint8_t*);
788    verify_latency_pkt(p, 0x01, 0, 8);
789    rte_pktmbuf_free(m);
790}
791
792// Testing latency packet receive path
793TEST_F(basic, latency2) {
794    rte_mbuf_t *m;
795    uint16_t pkt_size;
796    uint8_t port_id = 0;
797    uint8_t pkt_num = 1;
798    uint8_t l_pkt_mode;
799
800    l_pkt_mode = 0;
801    m = create_latency_test_pkt(l_pkt_mode, pkt_size, port_id, pkt_num);
802    test_latency_pkt_rcv(m, l_pkt_mode, 0, 2, true, 1, 0);
803
804    l_pkt_mode = L_PKT_SUBMODE_NO_REPLY;
805    m = create_latency_test_pkt(l_pkt_mode, pkt_size, port_id, pkt_num);
806    test_latency_pkt_rcv(m, l_pkt_mode, 1, 2, true, 3, 1);
807
808    // reply mode server
809    l_pkt_mode = L_PKT_SUBMODE_REPLY;
810    m = create_latency_test_pkt(l_pkt_mode, pkt_size, port_id, pkt_num);
811    test_latency_pkt_rcv(m, l_pkt_mode, 1, 2, true, 2, 1);
812
813    // reply mode client
814    l_pkt_mode = L_PKT_SUBMODE_REPLY;
815    m = create_latency_test_pkt(l_pkt_mode, pkt_size, port_id, pkt_num);
816    test_latency_pkt_rcv(m, l_pkt_mode, 0, 2, true, 3, 1);
817
818    l_pkt_mode = L_PKT_SUBMODE_0_SEQ;
819    m = create_latency_test_pkt(l_pkt_mode, pkt_size, port_id, pkt_num);
820    test_latency_pkt_rcv(m, l_pkt_mode, 0, 2, true, 0, 0);
821
822    // bad packet
823    m = create_latency_test_pkt(l_pkt_mode, pkt_size, port_id, pkt_num);
824    EthernetHeader *eth = (EthernetHeader *)rte_pktmbuf_mtod(m, uint8_t*);
825    eth->setNextProtocol(0x5);
826    test_latency_pkt_rcv(m, l_pkt_mode, 0, 2, false, 1, 0);
827}
828
829class CDummyLatencyHWBase : public CPortLatencyHWBase {
830public:
831    CDummyLatencyHWBase(){
832        m_queue=0;
833        m_port_id=0;
834    }
835
836    virtual int tx(rte_mbuf_t * m){
837        assert(m_queue==0);
838        //printf(" tx on port %d \n",m_port_id);
839      //  utl_DumpBuffer(stdout,rte_pktmbuf_mtod(m, uint8_t*),rte_pktmbuf_pkt_len(m),0);
840        m_queue=m;
841        return (0);
842    }
843
844    virtual rte_mbuf_t * rx(){
845        //printf(" rx on port %d \n",m_port_id);
846        rte_mbuf_t * m=0;
847        if (m_queue ) {
848            m=m_queue;
849            m_queue=0;
850        }
851
852        /*if ( m ){
853            utl_DumpBuffer(stdout,rte_pktmbuf_mtod(m , uint8_t*),rte_pktmbuf_pkt_len(m ),0);
854        } */
855        return ( m );
856    }
857
858    virtual uint16_t rx_burst(struct rte_mbuf **rx_pkts,
859                               uint16_t nb_pkts){
860        //printf(" rx on port %d \n",m_port_id);
861        rte_mbuf_t * m=rx();
862        if (m) {
863            rx_pkts[0]=m;
864            return (1);
865        }else{
866            return (0);
867        }
868    }
869
870
871private:
872    rte_mbuf_t * m_queue;
873public:
874    uint8_t      m_port_id;
875};
876
877// Testing latency statistics functions
878TEST_F(basic, latency3) {
879    CLatencyManager mg;
880    CLatencyManagerCfg  cfg;
881    CDummyLatencyHWBase dports[TREX_MAX_PORTS];
882    cfg.m_cps =10;
883    cfg.m_max_ports=4;
884    int i;
885    for (i = 0; i < TREX_MAX_PORTS; i++) {
886        dports[i].m_port_id=i;
887        cfg.m_ports[i] = &dports[i];
888    }
889
890    mg.Create(&cfg);
891
892    printf(" before sending \n");
893    mg.Dump(stdout);
894    std::string json;
895    mg.dump_json_v2(json);
896    printf(" %s \n",json.c_str());
897
898
899    EXPECT_EQ_UINT32(mg.is_active()?1:0, (uint32_t)0)<< "pass";
900
901    mg.start(8, false);
902    mg.stop();
903    mg.Dump(stdout);
904    mg.DumpShort(stdout);
905    mg.dump_json_v2(json);
906    printf(" %s \n",json.c_str());
907
908    mg.Delete();
909}
910
911TEST_F(basic, hist1) {
912
913    CTimeHistogram  hist1;
914
915    dsec_t dusec=1.0/1000000.0;
916
917    hist1.Create();
918    hist1.Add(dusec);
919    hist1.Add(2.0*dusec);
920    hist1.Add(11.0*dusec);
921    hist1.Add(110.0*dusec);
922    hist1.Add(1110.0*dusec);
923    hist1.Add(10110.0*dusec);
924    hist1.Add(40110.0*dusec);
925    hist1.Add(400110.0*dusec);
926    hist1.Dump(stdout);
927    hist1.Delete();
928}
929
930TEST_F(basic, rtsp1) {
931
932     CTestBasic t1;
933     CParserOption * po =&CGlobalInfo::m_options;
934     po->preview.setVMode(3);
935     po->preview.setFileWrite(true);
936     po->cfg_file ="cap2/rtsp_short1.yaml";
937     po->out_file ="exp/rtsp_short1";
938     bool res=t1.init();
939     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
940}
941
942TEST_F(basic, rtsp2) {
943
944     CTestBasic t1;
945     CParserOption * po =&CGlobalInfo::m_options;
946     po->preview.setVMode(3);
947     po->preview.setFileWrite(true);
948     po->cfg_file ="cap2/rtsp_short2.yaml";
949     po->out_file ="exp/rtsp_short2";
950     bool res=t1.init();
951     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
952}
953
954TEST_F(basic, rtsp3) {
955
956     CTestBasic t1;
957     CParserOption * po =&CGlobalInfo::m_options;
958     po->preview.setVMode(3);
959     po->preview.setFileWrite(true);
960     po->cfg_file ="cap2/rtsp_short3.yaml";
961     po->out_file ="exp/rtsp_short3";
962     t1.m_req_ports = 32000;
963     bool res=t1.init();
964     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
965}
966
967
968TEST_F(basic, rtsp1_ipv6) {
969
970     CTestBasic t1;
971     CParserOption * po =&CGlobalInfo::m_options;
972     po->preview.setVMode(3);
973     po->preview.set_ipv6_mode_enable(true);
974     po->preview.setFileWrite(true);
975     po->cfg_file ="cap2/rtsp_short1.yaml";
976     po->out_file ="exp/rtsp_short1_v6";
977     bool res=t1.init();
978     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
979     po->preview.set_ipv6_mode_enable(false);
980}
981
982TEST_F(basic, rtsp2_ipv6) {
983
984     CTestBasic t1;
985     CParserOption * po =&CGlobalInfo::m_options;
986     po->preview.setVMode(3);
987     po->preview.set_ipv6_mode_enable(true);
988     po->preview.setFileWrite(true);
989     po->cfg_file ="cap2/rtsp_short2.yaml";
990     po->out_file ="exp/rtsp_short2_v6";
991     bool res=t1.init();
992     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
993     po->preview.set_ipv6_mode_enable(false);
994}
995
996TEST_F(basic, rtsp3_ipv6) {
997
998     CTestBasic t1;
999     CParserOption * po =&CGlobalInfo::m_options;
1000     po->preview.setVMode(3);
1001     po->preview.set_ipv6_mode_enable(true);
1002     po->preview.setFileWrite(true);
1003     po->cfg_file ="cap2/rtsp_short3.yaml";
1004     po->out_file ="exp/rtsp_short3_v6";
1005     t1.m_req_ports = 32000;
1006     bool res=t1.init();
1007     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
1008     po->preview.set_ipv6_mode_enable(false);
1009}
1010
1011
1012TEST_F(basic, sip1) {
1013
1014     CTestBasic t1;
1015     CParserOption * po =&CGlobalInfo::m_options;
1016     po->preview.setVMode(3);
1017     po->preview.setFileWrite(true);
1018     po->cfg_file ="cap2/sip_short1.yaml";
1019     po->out_file ="exp/sip_short1";
1020     bool res=t1.init();
1021     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
1022}
1023
1024
1025TEST_F(basic, sip2) {
1026
1027     CTestBasic t1;
1028     CParserOption * po =&CGlobalInfo::m_options;
1029     po->preview.setVMode(3);
1030     po->preview.setFileWrite(true);
1031     po->cfg_file ="cap2/sip_short2.yaml";
1032     po->out_file ="exp/sip_short2";
1033     bool res=t1.init();
1034     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
1035}
1036
1037TEST_F(basic, sip3) {
1038
1039     CTestBasic t1;
1040     CParserOption * po =&CGlobalInfo::m_options;
1041     po->preview.setVMode(3);
1042     po->preview.setFileWrite(true);
1043     po->cfg_file ="cap2/sip_short2.yaml";
1044     po->out_file ="exp/sip_short3";
1045     t1.m_req_ports = 32000;
1046     bool res=t1.init();
1047     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
1048}
1049
1050
1051TEST_F(basic, sip1_ipv6) {
1052
1053     CTestBasic t1;
1054     CParserOption * po =&CGlobalInfo::m_options;
1055     po->preview.setVMode(3);
1056     po->preview.set_ipv6_mode_enable(true);
1057     po->preview.setFileWrite(true);
1058     po->cfg_file ="cap2/sip_short1.yaml";
1059     po->out_file ="exp/sip_short1_v6";
1060     bool res=t1.init();
1061     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
1062     po->preview.set_ipv6_mode_enable(false);
1063}
1064
1065
1066TEST_F(basic, sip2_ipv6) {
1067
1068     CTestBasic t1;
1069     CParserOption * po =&CGlobalInfo::m_options;
1070     po->preview.setVMode(3);
1071     po->preview.set_ipv6_mode_enable(true);
1072     po->preview.setFileWrite(true);
1073     po->cfg_file ="cap2/sip_short2.yaml";
1074     po->out_file ="exp/sip_short2_v6";
1075     bool res=t1.init();
1076     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
1077     po->preview.set_ipv6_mode_enable(false);
1078}
1079
1080TEST_F(basic, sip3_ipv6) {
1081
1082     CTestBasic t1;
1083     CParserOption * po =&CGlobalInfo::m_options;
1084     po->preview.setVMode(3);
1085     po->preview.set_ipv6_mode_enable(true);
1086     po->preview.setFileWrite(true);
1087     po->cfg_file ="cap2/sip_short2.yaml";
1088     po->out_file ="exp/sip_short3_v6";
1089     t1.m_req_ports = 32000;
1090     bool res=t1.init();
1091     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
1092     po->preview.set_ipv6_mode_enable(false);
1093}
1094
1095
1096TEST_F(basic, dyn1) {
1097
1098     CTestBasic t1;
1099     CParserOption * po =&CGlobalInfo::m_options;
1100     po->preview.setVMode(3);
1101     po->preview.setFileWrite(true);
1102     po->cfg_file ="cap2/dyn_pyld1.yaml";
1103     po->out_file ="exp/dyn_pyld1";
1104     bool res=t1.init();
1105     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
1106}
1107
1108TEST_F(basic, http1) {
1109
1110     CTestBasic t1;
1111     CParserOption * po =&CGlobalInfo::m_options;
1112     po->preview.setVMode(3);
1113     po->preview.setFileWrite(true);
1114     po->cfg_file ="cap2/http_plugin.yaml";
1115     po->out_file ="exp/http_plugin";
1116     bool res=t1.init();
1117     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
1118}
1119
1120TEST_F(basic, http1_ipv6) {
1121
1122     CTestBasic t1;
1123     CParserOption * po =&CGlobalInfo::m_options;
1124     po->preview.setVMode(3);
1125     po->preview.set_ipv6_mode_enable(true);
1126     po->preview.setFileWrite(true);
1127     po->cfg_file ="cap2/http_plugin.yaml";
1128     po->out_file ="exp/http_plugin_v6";
1129     bool res=t1.init();
1130     EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
1131     po->preview.set_ipv6_mode_enable(false);
1132}
1133
1134
1135
1136void delay(int msec);
1137
1138#if 0
1139
1140TEST_F(cpu, cpu1) {
1141    CCpuUtlDp cpu_dp;
1142    CCpuUtlCp cpu_cp;
1143    cpu_cp.Create(&cpu_dp);
1144    int i;
1145    for (i=0; i<5;i++) {
1146        cpu_cp.Update();
1147        double c=cpu_cp.GetVal();
1148        printf (" %f \n",c);
1149        EXPECT_EQ(c,(double)0.0);
1150
1151        delay(100);
1152    }
1153
1154    cpu_cp.Delete();
1155}
1156
1157TEST_F(cpu, cpu2) {
1158    CCpuUtlDp cpu_dp;
1159    CCpuUtlCp cpu_cp;
1160    cpu_cp.Create(&cpu_dp);
1161    int i;
1162    for (i=0; i<100;i++) {
1163        cpu_dp.start_work();
1164        cpu_cp.Update();
1165        double c1 = cpu_cp.GetVal();
1166        printf(" cpu %2.0f \n",c1);
1167        if (i>50) {
1168            int s=( c1<80 && c1>30)?1:0;
1169            EXPECT_EQ(s,1);
1170        }
1171        delay(1);
1172        if ((i%2)==1) {
1173            cpu_dp.commit();
1174        }else{
1175            cpu_dp.revert();
1176        }
1177    }
1178
1179    cpu_cp.Delete();
1180}
1181#endif
1182
1183#if 0
1184TEST_F(cpu, cpu3) {
1185    CCpuUtlDp cpu_dp;
1186    CCpuUtlCp cpu_cp;
1187    cpu_cp.Create(&cpu_dp);
1188    int i;
1189    for (i=0; i<200;i++) {
1190        cpu_dp.start_work();
1191        if (i%10==0) {
1192            cpu_cp.Update();
1193        }
1194        double c1 = cpu_cp.GetVal();
1195        if (i>150) {
1196            printf(" cpu %2.0f \n",c1);
1197            int s=( c1<11 && c1>8)?1:0;
1198            EXPECT_EQ(s,1);
1199        }
1200        delay(1);
1201        if ((i%10)==1) {
1202            cpu_dp.commit();
1203        }else{
1204            cpu_dp.revert();
1205        }
1206    }
1207    cpu_cp.Delete();
1208}
1209#endif
1210
1211
1212class timerwl  : public testing::Test {
1213 protected:
1214  virtual void SetUp() {
1215  }
1216  virtual void TearDown() {
1217  }
1218public:
1219};
1220
1221
1222
1223void  flow_callback(CFlowTimerHandle * timer_handle);
1224
1225class CTestFlow {
1226public:
1227	CTestFlow(){
1228		flow_id = 0;
1229        m_timer_handle.m_callback=flow_callback;
1230		m_timer_handle.m_object = (void *)this;
1231		m_timer_handle.m_id = 0x1234;
1232	}
1233
1234	uint32_t		flow_id;
1235	CFlowTimerHandle m_timer_handle;
1236public:
1237	void OnTimeOut(){
1238        printf(" timeout %d \n",flow_id);
1239	}
1240};
1241
1242void  flow_callback(CFlowTimerHandle * t){
1243    CTestFlow * lp=(CTestFlow *)t->m_object;
1244    assert(lp);
1245    assert(t->m_id==0x1234);
1246    lp->OnTimeOut();
1247}
1248
1249
1250TEST_F(timerwl, tw1) {
1251    CTimerWheel  my_tw;
1252
1253    CTestFlow f1;
1254    CTestFlow f2;
1255    CTestFlow f3;
1256    CTestFlow f4;
1257
1258    f1.flow_id=1;
1259    f2.flow_id=2;
1260    f3.flow_id=3;
1261    f4.flow_id=4;
1262    double time;
1263    EXPECT_EQ(my_tw.peek_top_time(time),false);
1264    my_tw.restart_timer(&f1.m_timer_handle,10.0);
1265    my_tw.restart_timer(&f2.m_timer_handle,5.0);
1266    my_tw.restart_timer(&f3.m_timer_handle,1.0);
1267    EXPECT_EQ(my_tw.peek_top_time(time),true);
1268    printf(" time %f \n",time);
1269    EXPECT_EQ(time ,1.0);
1270
1271    EXPECT_EQ(my_tw.peek_top_time(time),true);
1272    printf(" time %f \n",time);
1273    EXPECT_EQ(time ,1.0);
1274
1275    EXPECT_EQ(my_tw.peek_top_time(time),true);
1276    printf(" time %f \n",time);
1277    EXPECT_EQ(time ,1.0);
1278
1279    EXPECT_EQ(my_tw.handle(),true);
1280
1281    EXPECT_EQ(my_tw.peek_top_time(time),true);
1282    printf(" time %f \n",time);
1283    EXPECT_EQ(time ,5.0);
1284
1285    EXPECT_EQ(my_tw.handle(),true);
1286
1287    EXPECT_EQ(my_tw.peek_top_time(time),true);
1288    printf(" time %f \n",time);
1289    EXPECT_EQ(time ,10.0);
1290
1291    EXPECT_EQ(my_tw.handle(),true);
1292
1293}
1294
1295TEST_F(timerwl, tw2) {
1296    CTimerWheel  my_tw;
1297
1298    double mytime=0.1;
1299    int i;
1300    CTestFlow * af[100];
1301
1302    for (i=0; i<100; i++) {
1303        CTestFlow * f=new CTestFlow();
1304        af[i]=f;
1305        f->flow_id=i;
1306        my_tw.restart_timer(&f->m_timer_handle,mytime+10.0);
1307    }
1308    EXPECT_EQ(my_tw.m_st_alloc-my_tw.m_st_free,100);
1309
1310    my_tw.try_handle_events(mytime);
1311
1312    EXPECT_EQ(my_tw.m_st_alloc-my_tw.m_st_free,100);
1313
1314    for (i=0; i<100; i++) {
1315        CTestFlow * f=af[i];
1316        my_tw.stop_timer(&f->m_timer_handle);
1317    }
1318    EXPECT_EQ(my_tw.m_st_alloc-my_tw.m_st_free,100);
1319
1320    my_tw.try_handle_events(mytime);
1321
1322    /* expect to free all the object */
1323    EXPECT_EQ(my_tw.m_st_alloc-my_tw.m_st_free,0);
1324
1325}
1326
1327TEST_F(timerwl, check_stop_timer) {
1328
1329    CTimerWheel  my_tw;
1330
1331
1332    CTestFlow f1;
1333    CTestFlow f2;
1334    CTestFlow f3;
1335    CTestFlow f4;
1336
1337    f1.flow_id=1;
1338    f2.flow_id=2;
1339    f3.flow_id=3;
1340    f4.flow_id=4;
1341    double time;
1342    assert(my_tw.peek_top_time(time)==false);
1343    my_tw.restart_timer(&f1.m_timer_handle,10.0);
1344    my_tw.restart_timer(&f2.m_timer_handle,5.0);
1345    my_tw.restart_timer(&f3.m_timer_handle,1.0);
1346    my_tw.stop_timer(&f1.m_timer_handle);
1347
1348    assert(my_tw.peek_top_time(time)==true);
1349    printf(" time %f \n",time);
1350    EXPECT_EQ(time ,1.0);
1351
1352    assert(my_tw.peek_top_time(time)==true);
1353    printf(" time %f \n",time);
1354    EXPECT_EQ(time ,1.0);
1355
1356    assert(my_tw.peek_top_time(time)==true);
1357    printf(" time %f \n",time);
1358    EXPECT_EQ(time ,1.0);
1359
1360    assert(my_tw.handle());
1361
1362    assert(my_tw.peek_top_time(time)==true);
1363    printf(" time %f \n",time);
1364    EXPECT_EQ(time ,5.0);
1365
1366
1367    assert(my_tw.handle());
1368
1369    EXPECT_EQ(my_tw.peek_top_time(time) ,false);
1370    my_tw.Dump(stdout);
1371}
1372
1373
1374static int many_timers_flow_id=0;
1375
1376void  many_timers_flow_callback(CFlowTimerHandle * t){
1377    CTestFlow * lp=(CTestFlow *)t->m_object;
1378    assert(lp);
1379    assert(t->m_id==0x1234);
1380    assert(many_timers_flow_id==lp->flow_id);
1381    many_timers_flow_id--;
1382}
1383
1384
1385TEST_F(timerwl, many_timers) {
1386
1387    CTimerWheel  my_tw;
1388
1389	int i;
1390    for (i=0; i<100; i++) {
1391        CTestFlow * f= new CTestFlow();
1392        f->m_timer_handle.m_callback=many_timers_flow_callback;
1393        f->flow_id=(uint32_t)i;
1394        my_tw.restart_timer(&f->m_timer_handle,100.0-(double)i);
1395    }
1396    many_timers_flow_id=99;
1397
1398	double time;
1399    double ex_time=1.0;
1400    while (true) {
1401        if ( my_tw.peek_top_time(time) ){
1402            assert(time==ex_time);
1403            ex_time+=1.0;
1404            assert(my_tw.handle());
1405		}
1406		else{
1407			break;
1408		}
1409    }
1410
1411    my_tw.Dump(stdout);
1412
1413    EXPECT_EQ(my_tw.m_st_handle ,100);
1414    EXPECT_EQ(my_tw.m_st_alloc ,100);
1415    EXPECT_EQ(my_tw.m_st_free ,100);
1416    EXPECT_EQ(my_tw.m_st_start ,100);
1417
1418}
1419
1420void  many_timers_stop_flow_callback(CFlowTimerHandle * t){
1421    CTestFlow * lp=(CTestFlow *)t->m_object;
1422    assert(lp);
1423    assert(t->m_id==0x1234);
1424    assert(0);
1425}
1426
1427TEST_F(timerwl, many_timers_with_stop) {
1428    CTimerWheel  my_tw;
1429
1430    int i;
1431    for (i=0; i<100; i++) {
1432        CTestFlow * f= new CTestFlow();
1433        f->m_timer_handle.m_callback=many_timers_stop_flow_callback;
1434        f->flow_id=(uint32_t)i;
1435        my_tw.restart_timer(&f->m_timer_handle, 500.0 - (double)i);
1436        my_tw.restart_timer(&f->m_timer_handle, 1000.0 - (double)i);
1437        my_tw.restart_timer(&f->m_timer_handle, 100.0 - (double)i);
1438        my_tw.stop_timer(&f->m_timer_handle);
1439    }
1440
1441    double time;
1442    while (true) {
1443        if ( my_tw.peek_top_time(time) ){
1444            assert(0);
1445            assert(my_tw.handle());
1446        }
1447        else{
1448            break;
1449        }
1450    }
1451
1452    my_tw.Dump(stdout);
1453
1454
1455    EXPECT_EQ(my_tw.m_st_handle ,0);
1456    EXPECT_EQ(my_tw.m_st_alloc-my_tw.m_st_free ,0);
1457    EXPECT_EQ(my_tw.m_st_start ,300);
1458}
1459
1460
1461//////////////////////////////////////////////
1462class rx_check  : public testing::Test {
1463 protected:
1464  virtual void SetUp() {
1465      m_rx_check.Create();
1466
1467  }
1468  virtual void TearDown() {
1469      m_rx_check.Delete();
1470  }
1471public:
1472    RxCheckManager m_rx_check;
1473};
1474
1475
1476TEST_F(rx_check, rx_check_normal) {
1477    int i;
1478
1479    for (i=0; i<10; i++) {
1480        CRx_check_header rxh;
1481        rxh.clean();
1482
1483        rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
1484        rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
1485        rxh.m_time_stamp=0;
1486        rxh.m_magic=RX_CHECK_MAGIC;
1487        rxh.m_aging_sec=10;
1488        rxh.m_pkt_id=i;
1489        rxh.m_flow_size=10;
1490
1491        rxh.m_flow_id=7;
1492        rxh.set_dir(0);
1493        rxh.set_both_dir(0);
1494
1495        m_rx_check.handle_packet(&rxh);
1496    }
1497
1498    EXPECT_EQ(m_rx_check.m_stats.get_total_err(),0);
1499    EXPECT_EQ(m_rx_check.m_stats.m_add,1);
1500    EXPECT_EQ(m_rx_check.m_stats.m_remove,1);
1501    m_rx_check.Dump(stdout);
1502}
1503
1504
1505TEST_F(rx_check, rx_check_drop) {
1506
1507    int i;
1508
1509    for (i=0; i<10; i++) {
1510        CRx_check_header rxh;
1511        rxh.clean();
1512
1513        rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
1514        rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
1515        rxh.m_time_stamp=0;
1516        rxh.m_magic=RX_CHECK_MAGIC;
1517        rxh.m_aging_sec=10;
1518
1519        if (i==4) {
1520            /* drop packet 4 */
1521            continue;
1522        }
1523        rxh.m_pkt_id=i;
1524
1525        rxh.m_flow_size=10;
1526
1527        rxh.set_dir(0);
1528        rxh.set_both_dir(0);
1529
1530        rxh.m_flow_id=7;
1531
1532        rxh.m_flags=0;
1533        m_rx_check.handle_packet(&rxh);
1534    }
1535    m_rx_check.tw_drain();
1536    EXPECT_EQ(m_rx_check.m_stats.m_err_oo_late,1);
1537    EXPECT_EQ(m_rx_check.m_stats.m_add,1);
1538    EXPECT_EQ(m_rx_check.m_stats.m_remove,1);
1539    m_rx_check.Dump(stdout);
1540}
1541
1542TEST_F(rx_check, rx_check_ooo) {
1543
1544	m_rx_check.Create();
1545	int i;
1546
1547	for (i=0; i<10; i++) {
1548		CRx_check_header rxh;
1549        rxh.clean();
1550
1551        rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
1552        rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
1553		rxh.m_time_stamp=0;
1554		rxh.m_magic=RX_CHECK_MAGIC;
1555        rxh.m_aging_sec=10;
1556
1557        rxh.set_dir(0);
1558        rxh.set_both_dir(0);
1559
1560
1561		/* out of order */
1562		if (i==4) {
1563			rxh.m_pkt_id=5;
1564		}else{
1565			if (i==5) {
1566				rxh.m_pkt_id=4;
1567			}else{
1568				rxh.m_pkt_id=i;
1569			}
1570		}
1571
1572	    rxh.m_flow_size=10;
1573
1574	    rxh.m_flow_id=7;
1575
1576	    rxh.m_flags=0;
1577        m_rx_check.handle_packet(&rxh);
1578	}
1579	m_rx_check.tw_drain();
1580    EXPECT_EQ(m_rx_check.m_stats.m_err_oo_early,1);
1581    EXPECT_EQ(m_rx_check.m_stats.m_err_oo_late,2);
1582
1583	m_rx_check.Dump(stdout);
1584}
1585
1586
1587TEST_F(rx_check, rx_check_ooo_1) {
1588	int i;
1589
1590	for (i=0; i<10; i++) {
1591		CRx_check_header rxh;
1592        rxh.clean();
1593        rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
1594        rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
1595		rxh.m_time_stamp=0;
1596        rxh.set_dir(0);
1597        rxh.set_both_dir(0);
1598
1599		rxh.m_magic=RX_CHECK_MAGIC;
1600        rxh.m_aging_sec=10;
1601
1602		/* out of order */
1603		if (i==4) {
1604			rxh.m_pkt_id=56565;
1605		}else{
1606			if (i==5) {
1607				rxh.m_pkt_id=4;
1608			}else{
1609				rxh.m_pkt_id=i;
1610			}
1611		}
1612	    rxh.m_flow_size=10;
1613	    rxh.m_flow_id=7;
1614	    rxh.m_flags=0;
1615		m_rx_check.handle_packet(&rxh);
1616	}
1617	m_rx_check.tw_drain();
1618    EXPECT_EQ(m_rx_check.m_stats.m_err_wrong_pkt_id,1);
1619    EXPECT_EQ(m_rx_check.m_stats.m_err_oo_late,1);
1620
1621	m_rx_check.Dump(stdout);
1622}
1623
1624// start without first packet ( not FIF */
1625TEST_F(rx_check, rx_check_ooo_2) {
1626	int i;
1627
1628	for (i=0; i<10; i++) {
1629		CRx_check_header rxh;
1630        rxh.clean();
1631        rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
1632        rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
1633		rxh.m_time_stamp=0;
1634		rxh.m_magic=RX_CHECK_MAGIC;
1635        rxh.m_aging_sec=10;
1636
1637		/* out of order */
1638        rxh.set_dir(0);
1639        rxh.set_both_dir(0);
1640
1641
1642        if (i==0) {
1643            rxh.m_pkt_id=7;
1644        }else{
1645            if (i==7) {
1646                rxh.m_pkt_id=0;
1647            }else{
1648                rxh.m_pkt_id=i;
1649            }
1650        }
1651
1652	    rxh.m_flow_size=10;
1653	    rxh.m_flow_id=7;
1654	    rxh.m_flags=0;
1655		m_rx_check.handle_packet(&rxh);
1656	}
1657	m_rx_check.tw_drain();
1658    EXPECT_EQ(m_rx_check.m_stats.m_err_open_with_no_fif_pkt,1);
1659    EXPECT_EQ(m_rx_check.m_stats. m_err_oo_late,1);
1660	m_rx_check.Dump(stdout);
1661}
1662
1663
1664TEST_F(rx_check, rx_check_normal_two_dir) {
1665    int i;
1666
1667    for (i=0; i<10; i++) {
1668        CRx_check_header rxh;
1669        rxh.clean();
1670        rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
1671        rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
1672        rxh.m_time_stamp=0;
1673        rxh.m_magic=RX_CHECK_MAGIC;
1674        rxh.m_aging_sec=10;
1675
1676        rxh.m_pkt_id=i;
1677        rxh.m_flow_size=10;
1678
1679        rxh.m_flow_id=7;
1680        rxh.set_dir(0);
1681        rxh.set_both_dir(0);
1682
1683        m_rx_check.handle_packet(&rxh);
1684    }
1685
1686    EXPECT_EQ(m_rx_check.m_stats.get_total_err(),0);
1687    EXPECT_EQ(m_rx_check.m_stats.m_add,1);
1688    EXPECT_EQ(m_rx_check.m_stats.m_remove,1);
1689    m_rx_check.Dump(stdout);
1690}
1691
1692
1693
1694TEST_F(rx_check, rx_check_normal_two_dir_fails) {
1695    int i;
1696
1697    for (i=0; i<10; i++) {
1698        CRx_check_header rxh;
1699        rxh.clean();
1700        rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
1701        rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
1702        rxh.m_time_stamp=0;
1703        rxh.m_magic=RX_CHECK_MAGIC;
1704        rxh.m_aging_sec=10;
1705
1706        rxh.m_pkt_id=i;
1707        rxh.m_flow_size=10;
1708
1709        rxh.m_flow_id=7;
1710        rxh.set_dir(0);
1711        rxh.set_both_dir(1);
1712
1713        m_rx_check.handle_packet(&rxh);
1714    }
1715
1716    EXPECT_EQ(m_rx_check.m_stats.get_total_err(),0);
1717    EXPECT_EQ(m_rx_check.m_stats.m_add,1);
1718    EXPECT_EQ(m_rx_check.m_stats.m_remove,0);
1719    m_rx_check.Dump(stdout);
1720}
1721
1722TEST_F(rx_check, rx_check_normal_two_dir_ok) {
1723    int i;
1724
1725    CRx_check_header rxh;
1726    rxh.clean();
1727
1728    rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
1729    rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
1730    rxh.m_time_stamp=0;
1731    rxh.m_magic=RX_CHECK_MAGIC;
1732    rxh.m_aging_sec=10;
1733
1734    rxh.set_both_dir(1);
1735    rxh.m_flow_id=7;
1736    rxh.m_flow_size=10;
1737
1738    for (i=0; i<10; i++) {
1739        rxh.m_pkt_id=i;
1740        printf(" first : %d \n",i);
1741        rxh.set_dir(0);
1742        m_rx_check.handle_packet(&rxh);
1743    }
1744
1745    for (i=0; i<10; i++) {
1746        printf(" se : %d \n",i);
1747        rxh.m_pkt_id=i;
1748        rxh.set_dir(1);
1749        m_rx_check.handle_packet(&rxh);
1750    }
1751
1752    EXPECT_EQ(m_rx_check.m_stats.get_total_err(),0);
1753    EXPECT_EQ(m_rx_check.m_stats.m_add,1);
1754    EXPECT_EQ(m_rx_check.m_stats.m_remove,1);
1755    m_rx_check.Dump(stdout);
1756}
1757
1758TEST_F(rx_check, rx_check_normal_one_pkt_one_dir) {
1759    int i;
1760
1761    CRx_check_header rxh;
1762    rxh.clean();
1763
1764    rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
1765    rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
1766    rxh.m_time_stamp=0;
1767    rxh.m_magic=RX_CHECK_MAGIC;
1768    rxh.m_aging_sec=10;
1769
1770    rxh.set_both_dir(1);
1771    rxh.m_flow_id=7;
1772    rxh.m_flow_size=1;
1773
1774    for (i=0; i<1; i++) {
1775        rxh.m_pkt_id=i;
1776        printf(" first : %d \n",i);
1777        rxh.set_dir(0);
1778        m_rx_check.handle_packet(&rxh);
1779    }
1780    EXPECT_EQ(m_rx_check.m_stats.get_total_err(),0);
1781    EXPECT_EQ(m_rx_check.m_stats.m_add,1);
1782    EXPECT_EQ(m_rx_check.m_stats.m_remove,0);
1783    m_rx_check.Dump(stdout);
1784}
1785
1786TEST_F(rx_check, rx_check_normal_one_pkt_one_dir_0) {
1787    int i;
1788
1789    CRx_check_header rxh;
1790    rxh.clean();
1791
1792    rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
1793    rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
1794    rxh.m_time_stamp=0;
1795    rxh.m_magic=RX_CHECK_MAGIC;
1796    rxh.m_aging_sec=10;
1797
1798    rxh.set_both_dir(0);
1799    rxh.m_flow_id=7;
1800    rxh.m_flow_size=1;
1801
1802    for (i=0; i<1; i++) {
1803        rxh.m_pkt_id=i;
1804        rxh.set_dir(0);
1805        m_rx_check.handle_packet(&rxh);
1806    }
1807    EXPECT_EQ(m_rx_check.m_stats.get_total_err(),0);
1808    EXPECT_EQ(m_rx_check.m_stats.m_add,1);
1809    EXPECT_EQ(m_rx_check.m_stats.m_remove,1);
1810    m_rx_check.Dump(stdout);
1811}
1812
1813TEST_F(rx_check, rx_check_normal_one_pkt_two_dir_0) {
1814    int i;
1815
1816    CRx_check_header rxh;
1817    rxh.clean();
1818
1819    rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
1820    rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
1821    rxh.m_time_stamp=0;
1822    rxh.m_magic=RX_CHECK_MAGIC;
1823    rxh.m_aging_sec=10;
1824
1825    rxh.set_both_dir(1);
1826    rxh.m_flow_id=7;
1827    rxh.m_flow_size=1;
1828
1829    for (i=0; i<1; i++) {
1830        rxh.m_pkt_id=i;
1831        rxh.set_dir(0);
1832        m_rx_check.handle_packet(&rxh);
1833    }
1834
1835    for (i=0; i<1; i++) {
1836        rxh.m_pkt_id=i;
1837        rxh.set_dir(1);
1838        m_rx_check.handle_packet(&rxh);
1839    }
1840
1841    EXPECT_EQ(m_rx_check.m_stats.get_total_err(),0);
1842    EXPECT_EQ(m_rx_check.m_stats.m_add,1);
1843    EXPECT_EQ(m_rx_check.m_stats.m_remove,1);
1844    m_rx_check.Dump(stdout);
1845}
1846
1847TEST_F(rx_check, rx_check_normal_one_pkt_two_dir_err1) {
1848    int i;
1849
1850    CRx_check_header rxh;
1851    rxh.clean();
1852
1853    rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
1854    rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
1855    rxh.m_time_stamp=0;
1856    rxh.m_magic=RX_CHECK_MAGIC;
1857    rxh.m_aging_sec=10;
1858
1859    rxh.set_both_dir(1);
1860    rxh.m_flow_id=7;
1861    rxh.m_flow_size=10;
1862
1863    for (i=0; i<10; i++) {
1864        rxh.m_pkt_id=i;
1865        rxh.set_dir(0);
1866        m_rx_check.handle_packet(&rxh);
1867    }
1868
1869    for (i=0; i<10; i++) {
1870        if (i==0) {
1871            rxh.m_pkt_id=7;
1872        }else{
1873            if (i==7) {
1874                rxh.m_pkt_id=0;
1875            }else{
1876                rxh.m_pkt_id=i;
1877            }
1878        }
1879
1880        rxh.set_dir(1);
1881        m_rx_check.handle_packet(&rxh);
1882    }
1883
1884    EXPECT_EQ(m_rx_check.m_stats.m_err_oo_late,1);
1885    EXPECT_EQ(m_rx_check.m_stats.m_err_fif_seen_twice,1);
1886    EXPECT_EQ(m_rx_check.m_stats.m_add,1);
1887    EXPECT_EQ(m_rx_check.m_stats.m_remove,0);
1888    m_rx_check.Dump(stdout);
1889}
1890
1891
1892TEST_F(rx_check, rx_check_normal_two_dir_oo) {
1893    int i;
1894
1895    CRx_check_header rxh;
1896    rxh.clean();
1897
1898    rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
1899    rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
1900    rxh.m_time_stamp=0;
1901    rxh.m_magic=RX_CHECK_MAGIC;
1902    rxh.m_aging_sec=10;
1903
1904    rxh.set_both_dir(1);
1905    rxh.m_flow_id=7;
1906    rxh.m_flow_size=10;
1907
1908    for (i=0; i<10; i++) {
1909        rxh.m_pkt_id=i;
1910        rxh.set_dir(0);
1911        m_rx_check.handle_packet(&rxh);
1912    }
1913
1914    for (i=0; i<10; i++) {
1915
1916        if (i==4) {
1917            rxh.m_pkt_id=5;
1918        }else{
1919            if (i==5) {
1920                rxh.m_pkt_id=4;
1921            }else{
1922                rxh.m_pkt_id=i;
1923            }
1924        }
1925
1926
1927        rxh.set_dir(1);
1928        m_rx_check.handle_packet(&rxh);
1929    }
1930
1931    EXPECT_EQ(m_rx_check.m_stats.m_err_oo_early,1);
1932    EXPECT_EQ(m_rx_check.m_stats.m_err_oo_late,2);
1933    EXPECT_EQ(m_rx_check.m_stats.m_add,1);
1934    EXPECT_EQ(m_rx_check.m_stats.m_remove,0);
1935    m_rx_check.Dump(stdout);
1936}
1937
1938TEST_F(rx_check, rx_check_normal_aging) {
1939    int i;
1940
1941    CRx_check_header rxh;
1942    rxh.clean();
1943
1944    rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
1945    rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
1946    rxh.m_magic=RX_CHECK_MAGIC;
1947    rxh.m_aging_sec=2;
1948
1949    rxh.set_both_dir(0);
1950    rxh.m_flow_id=7;
1951    rxh.m_flow_size=10;
1952    rxh.m_template_id=13;
1953
1954    for (i=0; i<9; i++) {
1955        rxh.m_time_stamp=(uint32_t)now_sec();
1956        rxh.m_pkt_id=i;
1957        rxh.set_dir(0);
1958        rxh.m_pkt_id=i;
1959        if (i<5) {
1960            m_rx_check.m_cur_time = (now_sec()+10);
1961        }
1962        m_rx_check.tw_handle();
1963        m_rx_check.handle_packet(&rxh);
1964    }
1965
1966    EXPECT_EQ(m_rx_check.m_template_info[13].get_error_counter()>0?1:0,1);
1967    EXPECT_EQ(m_rx_check.m_stats.m_err_aged,4);
1968    EXPECT_EQ(m_rx_check.m_stats.m_err_open_with_no_fif_pkt,4 );
1969    EXPECT_EQ(m_rx_check.m_stats.m_err_oo_late,1);
1970
1971    m_rx_check.Dump(stdout);
1972}
1973
1974TEST_F(rx_check, rx_check_normal_no_aging) {
1975    int i;
1976
1977    CRx_check_header rxh;
1978    rxh.clean();
1979    rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
1980    rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
1981    rxh.m_magic=RX_CHECK_MAGIC;
1982    rxh.m_aging_sec=10;
1983
1984    rxh.set_both_dir(0);
1985    rxh.m_flow_id=7;
1986    rxh.m_flow_size=10;
1987
1988    for (i=0; i<9; i++) {
1989        rxh.m_time_stamp=(uint32_t)now_sec();
1990        rxh.m_pkt_id=i;
1991        rxh.set_dir(0);
1992        rxh.m_pkt_id=i;
1993        m_rx_check.tw_handle();
1994        m_rx_check.handle_packet(&rxh);
1995    }
1996
1997    EXPECT_EQ(m_rx_check.m_stats.get_total_err(),0);
1998    EXPECT_EQ(m_rx_check.m_stats.m_add,1);
1999    EXPECT_EQ(m_rx_check.m_stats.m_remove,0);
2000}
2001
2002
2003///////////////////////////////////////////////////////////////
2004// check the generation of template and check sample of it
2005
2006
2007class CRxCheckCallbackBase {
2008public:
2009    virtual void handle_packet(rte_mbuf  * m)=0;
2010    void * obj;
2011};
2012
2013class CRxCheckIF : public CVirtualIF {
2014
2015public:
2016    CRxCheckIF(){
2017        m_callback=NULL;
2018        m_raw=NULL;
2019        m_one_dir=true;
2020        m_store_pcfg=false;
2021    }
2022public:
2023
2024    virtual int open_file(std::string file_name){
2025        m_raw = new CCapPktRaw();
2026        assert(m_raw);
2027        return (0);
2028    }
2029
2030    virtual int close_file(void){
2031        assert(m_raw);
2032        m_raw->raw=0;
2033        delete m_raw;
2034        return (0);
2035    }
2036
2037
2038    /**
2039     * send one packet
2040     *
2041     * @param node
2042     *
2043     * @return
2044     */
2045    virtual int send_node(CGenNode * node);
2046
2047
2048    virtual int update_mac_addr_from_global_cfg(pkt_dir_t       dir, uint8_t * p){
2049        return (0);
2050    }
2051
2052
2053    /**
2054     * flush all pending packets into the stream
2055     *
2056     * @return
2057     */
2058    virtual int flush_tx_queue(void){
2059        return (0);
2060    }
2061
2062
2063public:
2064    bool                      m_one_dir;
2065    bool                      m_store_pcfg;
2066    CErfIF                    erf_vif;
2067    CCapPktRaw              * m_raw;
2068    CRxCheckCallbackBase    * m_callback;
2069};
2070
2071
2072int CRxCheckIF::send_node(CGenNode * node){
2073
2074    CFlowPktInfo * lp=node->m_pkt_info;
2075    rte_mbuf_t * m=lp->generate_new_mbuf(node);
2076
2077    /* update mac addr dest/src 12 bytes */
2078    uint8_t *p=(uint8_t *)m_raw->raw;
2079    uint8_t p_id = node->m_pkt_info->m_pkt_indication.m_desc.IsInitSide()?0:1;
2080    memcpy(p,CGlobalInfo::m_options.get_dst_src_mac_addr(p_id),12);
2081
2082    if ( unlikely( node->is_rx_check_enabled() ) ) {
2083        lp->do_generate_new_mbuf_rxcheck(m, node, m_one_dir);
2084    }
2085
2086    fill_pkt(m_raw,m);
2087    CPktNsecTimeStamp t_c(node->m_time);
2088    m_raw->time_nsec = t_c.m_time_nsec;
2089    m_raw->time_sec  = t_c.m_time_sec;
2090    m_raw->setInterface(node->m_pkt_info->m_pkt_indication.m_desc.IsInitSide());
2091
2092    if (m_store_pcfg) {
2093        erf_vif.write_pkt(m_raw);
2094    }
2095
2096    if ((m_callback) && (node->is_rx_check_enabled()) ) {
2097        m_callback->handle_packet(m);
2098    }
2099
2100    // just free it
2101    rte_pktmbuf_free(m);
2102    return (0);
2103}
2104
2105
2106class CRxCheckBasic {
2107
2108public:
2109    CRxCheckBasic(){
2110        m_threads=1;
2111        lpVf=0;
2112    }
2113
2114    bool  init(void){
2115        CFlowGenList fl;
2116        fl.Create();
2117        fl.load_from_yaml(CGlobalInfo::m_options.cfg_file,m_threads);
2118        CGlobalInfo::m_options.set_rxcheck_const_ts();
2119
2120        fl.generate_p_thread_info(m_threads);
2121        CFlowGenListPerThread   * lpt;
2122        fl.m_threads_info[0]->set_vif(lpVf);
2123        int i;
2124        for (i=0; i<m_threads; i++) {
2125            lpt=fl.m_threads_info[i];
2126            lpt->start_generate_stateful("t1",CGlobalInfo::m_options.preview);
2127        }
2128        fl.Delete();
2129        return (true);
2130    }
2131
2132public:
2133    int           m_threads;
2134    CRxCheckIF   * lpVf;
2135};
2136
2137
2138class CRxCheck1 : public CRxCheckCallbackBase {
2139public:
2140
2141    virtual void handle_packet(rte_mbuf_t  * m){
2142        rte_pktmbuf_mtod(m, char*);
2143        CRx_check_header * rx_p;
2144        rte_mbuf_t  * m2 = m->next;
2145        rx_p=(CRx_check_header *)rte_pktmbuf_mtod(m2, char*);
2146        mg->handle_packet(rx_p);
2147        //pkt->Dump(stdout,1);
2148    }
2149    RxCheckManager * mg;
2150};
2151
2152
2153class rx_check_system  : public testing::Test {
2154 protected:
2155  virtual void SetUp() {
2156
2157      m_rx_check.m_callback=&m_callback;
2158      m_callback.mg   =&m_mg;
2159      m_mg.Create();
2160      CParserOption * po =&CGlobalInfo::m_options;
2161      po->preview.setVMode(0);
2162      po->preview.setFileWrite(true);
2163      po->preview.set_rx_check_enable(true);
2164
2165  }
2166
2167  virtual void TearDown() {
2168      m_mg.Delete();
2169  }
2170public:
2171    CRxCheckBasic  m_rxcs;
2172    CRxCheckIF     m_rx_check;
2173    CRxCheck1      m_callback;
2174    RxCheckManager m_mg;
2175
2176};
2177
2178
2179// check DNS yaml with sample of 1/2 check that there is no errors
2180TEST_F(rx_check_system, rx_system1) {
2181
2182    m_rxcs.lpVf=&m_rx_check;
2183    CParserOption * po =&CGlobalInfo::m_options;
2184
2185    po->m_rx_check_sample=2; /* sample rate */
2186    po->m_duration=100;
2187    po->cfg_file ="cap2/dns.yaml";
2188
2189    m_rxcs.init();
2190    m_mg.tw_drain();
2191
2192    m_mg.Dump(stdout);
2193
2194    EXPECT_EQ(m_mg.m_stats.get_total_err(),0);
2195}
2196
2197// check DNS with rxcheck and write results out to capture file
2198TEST_F(rx_check_system, rx_system1_dns) {
2199
2200    m_rxcs.lpVf=&m_rx_check;
2201    CParserOption * po =&CGlobalInfo::m_options;
2202
2203    po->m_rx_check_sample=1; /* sample rate */
2204    po->m_duration=1;
2205    po->cfg_file ="cap2/dns.yaml";
2206    m_rx_check.m_store_pcfg=true;
2207
2208    m_rx_check.erf_vif.set_review_mode(&CGlobalInfo::m_options.preview);
2209    m_rx_check.erf_vif.open_file("exp/dns_rxcheck.erf");
2210
2211    m_rxcs.init();
2212    m_mg.tw_drain();
2213    m_rx_check.erf_vif.close_file();
2214
2215    CErfCmp cmp;
2216    cmp.dump=1;
2217    EXPECT_EQ(cmp.compare("exp/dns_rxcheck.erf","exp/dns_rxcheck-ex.erf"),true);
2218}
2219
2220// check DNS yaml with sample of 1/4 using IPv6 packets
2221TEST_F(rx_check_system, rx_system1_ipv6) {
2222
2223    m_rxcs.lpVf=&m_rx_check;
2224    CParserOption * po =&CGlobalInfo::m_options;
2225    po->preview.set_ipv6_mode_enable(true);
2226
2227    po->m_rx_check_sample=4; /* sample rate */
2228    po->m_duration=100;
2229    po->cfg_file ="cap2/dns.yaml";
2230
2231    m_rxcs.init();
2232    m_mg.tw_drain();
2233
2234    m_mg.Dump(stdout);
2235
2236    EXPECT_EQ(m_mg.m_stats.get_total_err(),0);
2237    po->preview.set_ipv6_mode_enable(false);
2238}
2239
2240// check DNS with rxcheck using IPv6 packets
2241// and write results out to capture file
2242TEST_F(rx_check_system, rx_system1_dns_ipv6) {
2243
2244    m_rxcs.lpVf=&m_rx_check;
2245    CParserOption * po =&CGlobalInfo::m_options;
2246
2247    po->preview.set_ipv6_mode_enable(true);
2248    po->m_rx_check_sample=1; /* sample rate */
2249    po->m_duration=1;
2250    po->cfg_file ="cap2/dns.yaml";
2251    m_rx_check.m_store_pcfg=true;
2252
2253    m_rx_check.erf_vif.set_review_mode(&CGlobalInfo::m_options.preview);
2254    m_rx_check.erf_vif.open_file("exp/dns_ipv6_rxcheck.erf");
2255
2256    m_rxcs.init();
2257    m_mg.tw_drain();
2258    m_rx_check.erf_vif.close_file();
2259
2260    CErfCmp cmp;
2261    cmp.dump=1;
2262    EXPECT_EQ(cmp.compare("exp/dns_ipv6_rxcheck.erf","exp/dns_ipv6_rxcheck-ex.erf"),true);
2263    po->preview.set_ipv6_mode_enable(false);
2264}
2265
2266TEST_F(rx_check_system, rx_system2_plugin_one_dir) {
2267
2268    m_rxcs.lpVf=&m_rx_check;
2269    CParserOption * po =&CGlobalInfo::m_options;
2270
2271    po->m_rx_check_sample=2; /* sample rate */
2272    po->m_duration=100;
2273    po->cfg_file ="cap2/rtsp_short1.yaml";
2274
2275    m_rxcs.init();
2276    m_mg.tw_drain();
2277
2278    m_mg.Dump(stdout);
2279
2280    EXPECT_EQ(m_mg.m_stats.get_total_err(),0);
2281}
2282
2283// check HTTP with rxcheck and write results out to capture file
2284TEST_F(rx_check_system, rx_system2_plugin) {
2285
2286    m_rxcs.lpVf=&m_rx_check;
2287    CParserOption * po =&CGlobalInfo::m_options;
2288
2289    po->m_rx_check_sample=1; /* sample rate */
2290    po->m_duration=1;
2291    po->cfg_file ="cap2/rtsp_short1.yaml";
2292    m_rx_check.m_store_pcfg=true;
2293
2294    m_rx_check.erf_vif.set_review_mode(&CGlobalInfo::m_options.preview);
2295    m_rx_check.erf_vif.open_file("exp/rtsp_short1_rxcheck.erf");
2296
2297    m_rxcs.init();
2298    m_mg.tw_drain();
2299    m_rx_check.erf_vif.close_file();
2300
2301    CErfCmp cmp;
2302    cmp.dump=1;
2303    EXPECT_EQ(cmp.compare("exp/rtsp_short1_rxcheck.erf","exp/rtsp_short1_rxcheck-ex.erf"),true);
2304}
2305
2306// check DNS with rxcheck using IPv6 packets
2307// and write results out to capture file
2308TEST_F(rx_check_system, rx_system2_plugin_ipv6) {
2309
2310    m_rxcs.lpVf=&m_rx_check;
2311    CParserOption * po =&CGlobalInfo::m_options;
2312
2313    po->preview.set_ipv6_mode_enable(true);
2314    po->m_rx_check_sample=1; /* sample rate */
2315    po->m_duration=1;
2316    po->cfg_file ="cap2/rtsp_short1.yaml";
2317    m_rx_check.m_store_pcfg=true;
2318
2319    m_rx_check.erf_vif.set_review_mode(&CGlobalInfo::m_options.preview);
2320    m_rx_check.erf_vif.open_file("exp/rtsp_short1_ipv6_rxcheck.erf");
2321
2322    m_rxcs.init();
2323    m_mg.tw_drain();
2324    m_rx_check.erf_vif.close_file();
2325
2326    CErfCmp cmp;
2327    cmp.dump=1;
2328    EXPECT_EQ(cmp.compare("exp/rtsp_short1_ipv6_rxcheck.erf","exp/rtsp_short1_ipv6_rxcheck-ex.erf"),true);
2329    po->preview.set_ipv6_mode_enable(false);
2330}
2331
2332TEST_F(rx_check_system, rx_system2_plugin_two_dir) {
2333
2334    m_rxcs.lpVf=&m_rx_check;
2335    CParserOption * po =&CGlobalInfo::m_options;
2336
2337    po->m_rx_check_sample=2; /* sample rate */
2338    po->m_duration=100;
2339    po->cfg_file ="cap2/rtsp_short1_slow.yaml";
2340    m_rx_check.m_one_dir=false;
2341
2342    m_rxcs.init();
2343    m_mg.tw_drain();
2344
2345    m_mg.Dump(stdout);
2346
2347    EXPECT_EQ(m_mg.m_stats.get_total_err(),0);
2348}
2349
2350TEST_F(rx_check_system, rx_system2_plugin_two_dir_2) {
2351
2352    m_rxcs.lpVf=&m_rx_check;
2353    CParserOption * po =&CGlobalInfo::m_options;
2354
2355    po->m_rx_check_sample=2; /* sample rate */
2356    po->m_duration=100;
2357    po->cfg_file ="cap2/rtsp_short1.yaml";
2358    m_rx_check.m_one_dir=false;
2359
2360    m_rxcs.init();
2361    m_mg.tw_drain();
2362
2363    m_mg.Dump(stdout);
2364
2365    EXPECT_EQ(m_mg.m_stats.get_total_err(),0);
2366}
2367
2368TEST_F(rx_check_system, rx_system_two_dir) {
2369
2370    m_rxcs.lpVf=&m_rx_check;
2371    CParserOption * po =&CGlobalInfo::m_options;
2372
2373    po->m_rx_check_sample=2; /* sample rate */
2374    po->m_duration=100;
2375    po->cfg_file ="cap2/dns.yaml";
2376    m_rx_check.m_one_dir=false;
2377
2378    m_rxcs.init();
2379    m_mg.tw_drain();
2380
2381    m_mg.Dump(stdout);
2382
2383    EXPECT_EQ(m_mg.m_stats.get_total_err(),0);
2384}
2385
2386
2387TEST_F(rx_check_system, rx_json) {
2388
2389    m_rxcs.lpVf=&m_rx_check;
2390    CParserOption * po =&CGlobalInfo::m_options;
2391
2392    po->m_rx_check_sample=2; /* sample rate */
2393    po->m_duration=100;
2394    po->cfg_file ="cap2/dns.yaml";
2395
2396    m_rxcs.init();
2397    m_mg.tw_drain();
2398
2399    std::string json;
2400    m_mg.dump_json(json);
2401    printf(" %s \n",json.c_str());
2402}
2403
2404class nat_check_flow_table  : public testing::Test {
2405 protected:
2406  virtual void SetUp() {
2407  }
2408
2409  virtual void TearDown() {
2410  }
2411public:
2412    CNatCheckFlowTable m_ft;
2413};
2414
2415TEST_F(nat_check_flow_table, test1) {
2416    m_ft.test();
2417};
2418
2419//////////////////////////////////////////////////////////////
2420
2421
2422class CNatCheck1 : public CRxCheckCallbackBase {
2423public:
2424
2425    virtual void handle_packet(rte_mbuf_t  * m){
2426            char *mp=rte_pktmbuf_mtod(m, char*);
2427            CNatOption * option=(CNatOption *)(mp+14+20);
2428            IPHeader * ipv4=(IPHeader *)(mp+14);
2429            if ( ipv4->getHeaderLength()>20 ) {
2430                assert(ipv4->getTimeToLive()==255);
2431                /* ip option packet */
2432                printf(" rx got ip option packet ! \n");
2433                mg->handle_packet_ipv4(option, ipv4, true);
2434                delay(10);          // delay for queue flush
2435                mg->handle_aging(); // flush the RxRing
2436            }
2437    }
2438    CNatRxManager * mg;
2439};
2440
2441
2442
2443class nat_check_system  : public testing::Test {
2444 protected:
2445  virtual void SetUp() {
2446      m_rx_check.m_callback=&m_callback;
2447      m_callback.mg   =&m_mg;
2448      m_mg.Create();
2449      CParserOption * po =&CGlobalInfo::m_options;
2450      po->preview.setVMode(0);
2451      po->preview.setFileWrite(true);
2452      po->m_learn_mode = CParserOption::LEARN_MODE_IP_OPTION;
2453  }
2454
2455  virtual void TearDown() {
2456      CParserOption * po =&CGlobalInfo::m_options;
2457      po->m_learn_mode = CParserOption::LEARN_MODE_DISABLED;
2458      m_mg.Delete();
2459  }
2460public:
2461    CRxCheckBasic   m_rxcs;
2462    CRxCheckIF      m_rx_check;
2463    CNatCheck1      m_callback;
2464    CNatRxManager   m_mg;
2465
2466};
2467
2468#if 0
2469
2470TEST_F(nat_check_system, nat_system1) {
2471
2472    m_rxcs.lpVf=&m_rx_check;
2473    CParserOption * po =&CGlobalInfo::m_options;
2474    po->m_duration=2;
2475    po->cfg_file ="cap2/dns.yaml";
2476
2477    m_rxcs.init();
2478    m_mg.Dump(stdout);
2479
2480    //EXPECT_EQ(m_mg.m_stats.get_total_err(),0);
2481}
2482
2483#endif
2484
2485//////////////////////////////////////////////////////////////
2486
2487class file_flow_info  : public testing::Test {
2488
2489protected:
2490  virtual void SetUp() {
2491      assert(m_flow_info.Create());
2492  }
2493
2494  virtual void TearDown() {
2495      m_flow_info.Delete();
2496  }
2497public:
2498    void load_cap_file_errors_helper(std::string cap_file, enum CCapFileFlowInfo::load_cap_file_err expect);
2499
2500public:
2501    CCapFileFlowInfo m_flow_info;
2502};
2503
2504TEST_F(file_flow_info, f1) {
2505    m_flow_info.load_cap_file("cap2/delay_10_rtp_250k_short.pcap",1,7) ;
2506    m_flow_info.update_info();
2507    //m_flow_info.Dump(stdout);
2508
2509    int i;
2510    for (i=0; i<m_flow_info.Size(); i++) {
2511            CFlowPktInfo * lp=m_flow_info.GetPacket((uint32_t)i);
2512            uint16_t flow_id=lp->m_pkt_indication.m_desc.getFlowId();
2513            switch (flow_id) {
2514            case 0:
2515                EXPECT_EQ(lp->m_pkt_indication.m_desc.GetMaxPktsPerFlow(),23);
2516                EXPECT_EQ(lp->m_pkt_indication.m_desc.GetMaxFlowTimeout(),64);
2517                EXPECT_EQ(lp->m_pkt_indication.m_desc.IsBiDirectionalFlow(),1);
2518                break;
2519            case 1:
2520                EXPECT_EQ(lp->m_pkt_indication.m_desc.GetMaxPktsPerFlow(),7);
2521                EXPECT_EQ(lp->m_pkt_indication.m_desc.GetMaxFlowTimeout(),10);
2522                EXPECT_EQ(lp->m_pkt_indication.m_desc.IsBiDirectionalFlow(),0);
2523
2524                break;
2525            case 2:
2526                EXPECT_EQ(lp->m_pkt_indication.m_desc.GetMaxPktsPerFlow(),7);
2527                EXPECT_EQ(lp->m_pkt_indication.m_desc.GetMaxFlowTimeout(),5);
2528                EXPECT_EQ(lp->m_pkt_indication.m_desc.IsBiDirectionalFlow(),0);
2529
2530                break;
2531            default:
2532                assert(0);
2533            }
2534    }
2535
2536}
2537
2538TEST_F(file_flow_info, f2) {
2539    m_flow_info.load_cap_file("cap2/citrix.pcap",1,0) ;
2540    m_flow_info.update_info();
2541
2542
2543    int i;
2544    for (i=0; i<m_flow_info.Size(); i++) {
2545            CFlowPktInfo * lp=m_flow_info.GetPacket((uint32_t)i);
2546            uint16_t flow_id=lp->m_pkt_indication.m_desc.getFlowId();
2547            switch (flow_id) {
2548            case 0:
2549                EXPECT_EQ(lp->m_pkt_indication.m_desc.GetMaxPktsPerFlow(),271);
2550                EXPECT_EQ(lp->m_pkt_indication.m_desc.GetMaxFlowTimeout(),5);
2551                break;
2552            default:
2553                assert(0);
2554            }
2555    }
2556}
2557
2558TEST_F(file_flow_info, http_two_dir) {
2559    m_flow_info.load_cap_file("avl/delay_10_http_browsing_0.pcap",1,0) ;
2560    m_flow_info.update_info();
2561    CFlowPktInfo * lp=m_flow_info.GetPacket((uint32_t)0);
2562    EXPECT_EQ(lp->m_pkt_indication.m_desc.IsOneDirectionalFlow(),0);
2563}
2564
2565TEST_F(file_flow_info, one_dir) {
2566
2567    m_flow_info.load_cap_file("avl/delay_rtp_160k_1_1_0.pcap",1,0) ;
2568    m_flow_info.update_info();
2569    CFlowPktInfo * lp=m_flow_info.GetPacket((uint32_t)0);
2570    EXPECT_EQ(lp->m_pkt_indication.m_desc.IsOneDirectionalFlow(),1);
2571}
2572
2573
2574
2575TEST_F(file_flow_info, nat_option_check) {
2576    uint8_t buffer[8];
2577    CNatOption *lp=(CNatOption *)&buffer[0];
2578    lp->set_init_ipv4_header();
2579    lp->set_fid(0x12345678);
2580    lp->set_thread_id(7);
2581    lp->dump(stdout);
2582    EXPECT_EQ(lp->is_valid_ipv4_magic(),true);
2583
2584    lp->set_init_ipv6_header();
2585    lp->dump(stdout);
2586    EXPECT_EQ(lp->is_valid_ipv6_magic(),true);
2587}
2588
2589TEST_F(file_flow_info, http_add_ipv4_option) {
2590    m_flow_info.load_cap_file("avl/delay_10_http_browsing_0.pcap",1,0) ;
2591    m_flow_info.update_info();
2592    CFlowPktInfo * lp=m_flow_info.GetPacket((uint32_t)0);
2593    printf(" before the change \n");
2594    //lp->Dump(stdout);
2595    //lp->m_packet->Dump(stdout,1);
2596    CNatOption *lpNat =(CNatOption *)lp->push_ipv4_option_offline(8);
2597    lpNat->set_init_ipv4_header();
2598    lpNat->set_fid(0x12345678);
2599    lpNat->set_thread_id(7);
2600    lp->m_pkt_indication.l3.m_ipv4->updateCheckSum();
2601    m_flow_info.save_to_erf("exp/http1_with_option.pcap",true);
2602
2603    m_flow_info.Delete();
2604    CErfCmp cmp;
2605    cmp.dump=1;
2606    EXPECT_EQ(cmp.compare("exp/http1_with_option.pcap","exp/http1_with_option-ex.pcap"),true);
2607}
2608
2609TEST_F(file_flow_info, http_add_ipv6_option) {
2610    /* convert it to ipv6 */
2611    CParserOption * po =&CGlobalInfo::m_options;
2612    po->preview.set_ipv6_mode_enable(true);
2613
2614    m_flow_info.load_cap_file("avl/delay_10_http_browsing_0.pcap",1,0) ;
2615    m_flow_info.update_info();
2616    CFlowPktInfo * lp=m_flow_info.GetPacket((uint32_t)0);
2617    //lp->Dump(stdout);
2618    //lp->m_packet->Dump(stdout,1);
2619    CNatOption *lpNat =(CNatOption *)lp->push_ipv6_option_offline(8);
2620    lpNat->set_init_ipv6_header();
2621    lpNat->set_fid(0x12345678);
2622    lpNat->set_thread_id(7);
2623    m_flow_info.save_to_erf("exp/http1_with_option_ipv6.pcap",true);
2624    m_flow_info.Delete();
2625    CErfCmp cmp;
2626    cmp.dump=1;
2627    EXPECT_EQ(cmp.compare("exp/http1_with_option_ipv6.pcap","exp/http1_with_option_ipv6-ex.pcap"),true);
2628    po->preview.set_ipv6_mode_enable(false);
2629}
2630
2631void file_flow_info::load_cap_file_errors_helper(std::string cap_file, enum CCapFileFlowInfo::load_cap_file_err expect) {
2632    enum CCapFileFlowInfo::load_cap_file_err err;
2633
2634    err = m_flow_info.load_cap_file(cap_file, 1, 0);
2635    if (err == 0) err = m_flow_info.is_valid_template_load_time();
2636    if (err != expect) {
2637        printf("Error in testing file %s. Expected error to be %d, but it is %d\n", cap_file.c_str(), expect, err);
2638    }
2639    assert (err == expect);
2640}
2641
2642// Test error conditions when loading cap file
2643TEST_F(file_flow_info, load_cap_file_errors) {
2644    CParserOption *po = &CGlobalInfo::m_options;
2645
2646    po->m_learn_mode = CParserOption::LEARN_MODE_DISABLED;
2647    load_cap_file_errors_helper("/tmp/not_exist", CCapFileFlowInfo::kFileNotExist);
2648    // file format not supported
2649    load_cap_file_errors_helper("cap2/dns.yaml", CCapFileFlowInfo::kFileNotExist);
2650    load_cap_file_errors_helper("cap2/dns.pcap", CCapFileFlowInfo::kOK);
2651    load_cap_file_errors_helper("./exp/tcp_no_syn.pcap", CCapFileFlowInfo::kOK);
2652    load_cap_file_errors_helper("./exp/many_ip_options.pcap", CCapFileFlowInfo::kOK);
2653    // Non IP packet
2654    load_cap_file_errors_helper("./exp/bad_not_ip.pcap", CCapFileFlowInfo::kPktProcessFail);
2655    load_cap_file_errors_helper("./exp/tcp_2_pkts.pcap", CCapFileFlowInfo::kOK);
2656    // more than 1 flow in cap file
2657    load_cap_file_errors_helper("./exp/syn_attack.pcap",  CCapFileFlowInfo::kCapFileErr);
2658
2659    po->m_learn_mode = CParserOption::LEARN_MODE_IP_OPTION;
2660    load_cap_file_errors_helper("cap2/dns.pcap", CCapFileFlowInfo::kOK);
2661    load_cap_file_errors_helper("./exp/tcp_no_syn.pcap", CCapFileFlowInfo::kOK);
2662    load_cap_file_errors_helper("./exp/many_ip_options.pcap", CCapFileFlowInfo::kIPOptionNotAllowed);
2663    load_cap_file_errors_helper("./exp/tcp_2_pkts.pcap", CCapFileFlowInfo::kOK);
2664
2665    po->m_learn_mode = CParserOption::LEARN_MODE_TCP_ACK_NO_SERVER_SEQ_RAND;
2666    // udp in tcp learn mode
2667    load_cap_file_errors_helper("cap2/dns.pcap", CCapFileFlowInfo::kNoTCPFromServer);
2668    // no SYN in first packet
2669    load_cap_file_errors_helper("./exp/tcp_no_syn.pcap", CCapFileFlowInfo::kNoSyn);
2670    // TCP flags offset is too big. We don't allow IP option, so can comment this.
2671    // open this if we do allow IP options in the future
2672    //    load_cap_file_errors_helper("./exp/many_ip_options.pcap", CCapFileFlowInfo::kTCPOffsetTooBig);
2673    load_cap_file_errors_helper("./exp/tcp_2_pkts.pcap", CCapFileFlowInfo::kOK);
2674    load_cap_file_errors_helper("./exp/no_tcp_syn_ack.pcap",  CCapFileFlowInfo::kOK);
2675
2676    po->m_learn_mode = CParserOption::LEARN_MODE_TCP_ACK;
2677    // too short. only two packets
2678    load_cap_file_errors_helper("./exp/tcp_2_pkts.pcap", CCapFileFlowInfo::kTCPLearnModeBadFlow);
2679    // no SYN+ACK
2680    load_cap_file_errors_helper("./exp/no_tcp_syn_ack.pcap",  CCapFileFlowInfo::kNoTCPSynAck);
2681    // IPG between TCP handshake packets too low
2682    load_cap_file_errors_helper("./exp/tcp_low_ipg.pcap",  CCapFileFlowInfo::kTCPIpgTooLow);
2683}
2684
2685//////////////////////////////////////////////////////////////
2686
2687class time_histogram  : public testing::Test {
2688
2689protected:
2690  virtual void SetUp() {
2691      m_hist.Create();
2692  }
2693
2694  virtual void TearDown() {
2695      m_hist.Delete();
2696  }
2697public:
2698    CTimeHistogram m_hist;
2699};
2700
2701TEST_F(time_histogram, test_average) {
2702    int i;
2703    int j;
2704    for (j = 0; j < 10; j++) {
2705        for (i = 0; i <= 2000; i++) {
2706            m_hist.Add(10e-7 * i);
2707        }
2708        m_hist.update();
2709        // Latency is calculated using low pass filter, with initial value of 0
2710        EXPECT_EQ(m_hist.get_average_latency(), 1000.0 - (1000.0 / (2 << j)));
2711        EXPECT_EQ(m_hist.get_count(), 2001 * (j+1));
2712        EXPECT_EQ(m_hist.get_high_count(), 2001 * (j+1) - (11 * (j+1)));
2713        EXPECT_EQ(m_hist.get_max_latency(), 2000);
2714    }
2715
2716    m_hist.Dump(stdout);
2717}
2718
2719TEST_F(time_histogram, test_json) {
2720    int i;
2721    int j;
2722    for (j=0; j<10; j++) {
2723        for (i=0; i<100; i++) {
2724            m_hist.Add(10e-6);
2725        }
2726        for (i=0; i<100; i++) {
2727            m_hist.Add(10e-3);
2728        }
2729        m_hist.update();
2730    }
2731
2732    m_hist.Dump(stdout);
2733    std::string  json ;
2734    m_hist.dump_json("myHis",json );
2735    printf(" %s \n",json.c_str());
2736}
2737
2738
2739
2740class gt_jitter  : public testing::Test {
2741
2742protected:
2743  virtual void SetUp() {
2744  }
2745
2746  virtual void TearDown() {
2747  }
2748public:
2749    CJitter m_jitter;
2750};
2751
2752
2753class gt_jitter_uint  : public testing::Test {
2754
2755protected:
2756  virtual void SetUp() {
2757  }
2758
2759  virtual void TearDown() {
2760  }
2761public:
2762    CJitterUint m_jitter;
2763};
2764
2765
2766
2767TEST_F(gt_jitter, jitter1) {
2768    int i;
2769    double a=0.000030;
2770    for (i=0; i<100; i++) {
2771        if (i%2) {
2772            a+=0.000100;
2773        }else{
2774            a-=0.000100;
2775        }
2776        m_jitter.calc(a);
2777    }
2778    EXPECT_EQ((uint32_t)(m_jitter.get_jitter()*1000000.0), 99);
2779}
2780
2781TEST_F(gt_jitter_uint, jitter2) {
2782    int i;
2783    int32_t a=30;
2784    for (i=0; i<100; i++) {
2785        if (i%2) {
2786            a+=20;
2787        }else{
2788            a-=20;
2789        }
2790        m_jitter.calc(a);
2791    }
2792    EXPECT_EQ((uint32_t)(m_jitter.get_jitter()), 19);
2793}
2794
2795
2796class gt_ring  : public testing::Test {
2797
2798protected:
2799  virtual void SetUp() {
2800  }
2801
2802  virtual void TearDown() {
2803  }
2804public:
2805};
2806
2807TEST_F(gt_ring, ring1) {
2808
2809    CTRingSp<uint32_t> my;
2810    bool res=my.Create("a",1024,0);
2811    assert(res);
2812
2813    int i;
2814    for (i=0; i<10; i++) {
2815        uint32_t *p=new uint32_t();
2816        *p=i;
2817        assert(my.Enqueue(p)==0);
2818    }
2819    for (i=0; i<10; i++) {
2820        uint32_t *p;
2821        assert(my.Dequeue(p)==0);
2822        EXPECT_EQ_UINT32(*p, i);
2823    }
2824    uint32_t *p;
2825    assert(my.Dequeue(p)!=0);
2826
2827    EXPECT_EQ(my.isEmpty(), true);
2828    EXPECT_EQ(my.isFull(), false);
2829
2830    my.Delete();
2831}
2832
2833
2834TEST_F(gt_ring, ring2) {
2835    CMessagingManager ringmg;
2836    ringmg.Create(8, "test");
2837
2838    int i;
2839    for (i=0; i<8; i++) {
2840        CNodeRing * ln=ringmg.getRingDpToCp(i);
2841        assert(ln);
2842        CGenNode * node=new CGenNode();
2843        node->m_flow_id=i;
2844        assert(ln->Enqueue(node)==0);
2845    }
2846
2847    for (i=0; i<8; i++) {
2848        CNodeRing * ln=ringmg.getRingDpToCp(i);
2849        assert(ln);
2850        CGenNode * node;
2851        assert(ln->Dequeue(node)==0);
2852        EXPECT_EQ(node->m_flow_id, i);
2853        delete node;
2854    }
2855
2856    ringmg.Delete();
2857}
2858
2859
2860
2861
2862
2863
2864
2865void my_free_map_uint32_t(uint32_t *p){
2866    printf("before free %d \n",*p);
2867    delete p;
2868}
2869
2870
2871TEST_F(gt_ring, ring3) {
2872
2873    typedef  CGenericMap<uint32_t,uint32_t> my_test_map;
2874    my_test_map my_map;
2875
2876    my_map.Create();
2877    int i;
2878
2879    uint32_t *p;
2880    for (i=0; i<10;i++) {
2881        p=new uint32_t(i);
2882        my_map.add((uint32_t)i,p);
2883    }
2884
2885    for (i=0; i<10;i++) {
2886        p=my_map.lookup((uint32_t)i);
2887        printf(" %d \n",*p);
2888    }
2889
2890    my_map.remove_all(my_free_map_uint32_t);
2891    #if 0
2892    for (i=0; i<10;i++) {
2893        p=my_map.remove((uint32_t)i);
2894        assert(p);
2895        delete p;
2896    }
2897    #endif
2898    my_map.Delete();
2899}
2900
2901
2902class gt_conf  : public testing::Test {
2903
2904protected:
2905  virtual void SetUp() {
2906  }
2907
2908  virtual void TearDown() {
2909  }
2910public:
2911};
2912
2913
2914#if 0
2915TEST_F(gt_conf, t1) {
2916    CPlatformYamlInfo info;
2917    info.load_from_yaml_file("cfg/ex1.yaml");
2918    info.Dump(stdout);
2919    CPlatformSocketInfoConfig cfg;
2920    cfg.Create(&info.m_platform);
2921
2922    cfg.set_latency_thread_is_enabled(true);
2923    cfg.set_number_of_dual_ports(1);
2924    cfg.set_number_of_threads_per_ports(1);
2925
2926
2927    cfg.sanity_check();
2928    cfg.dump(stdout);
2929}
2930
2931#endif
2932
2933
2934