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