summaryrefslogtreecommitdiffstats
path: root/src/bp_gtest.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'src/bp_gtest.cpp')
-rwxr-xr-xsrc/bp_gtest.cpp2792
1 files changed, 2792 insertions, 0 deletions
diff --git a/src/bp_gtest.cpp b/src/bp_gtest.cpp
new file mode 100755
index 00000000..020276cf
--- /dev/null
+++ b/src/bp_gtest.cpp
@@ -0,0 +1,2792 @@
+/*
+ Hanoh Haim
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2015-2015 Cisco Systems, Inc.
+
+Licensed under the Apache License, Version 2.0 (the "License");
+you may not use this file except in compliance with the License.
+You may obtain a copy of the License at
+
+ http://www.apache.org/licenses/LICENSE-2.0
+
+Unless required by applicable law or agreed to in writing, software
+distributed under the License is distributed on an "AS IS" BASIS,
+WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+See the License for the specific language governing permissions and
+limitations under the License.
+*/
+
+#include "bp_sim.h"
+#include <common/gtest.h>
+#include <common/basic_utils.h>
+#include "utl_cpuu.h"
+#include "timer_wheel_pq.h"
+#include "rx_check.h"
+#include "time_histogram.h"
+#include "utl_jitter.h"
+#include "CRing.h"
+#include "msg_manager.h"
+#include <common/cgen_map.h>
+#include "platform_cfg.h"
+
+int test_policer(){
+ CPolicer policer;
+
+ policer.set_cir( 100.0);
+ policer.set_level(0.0);
+ policer.set_bucket_size(100.0);
+
+ double t;
+ uint32_t c=0;
+ for (t=0.001;t<10.0; t=t+0.001) {
+ if ( policer.update(1.0,t) ){
+ c++;
+ printf(" %f \n",t);
+ }
+ }
+ printf(" %u \n",c);
+ if ( ( c > 970.0) && ( c < 1000.0) ) {
+ printf(" ok \n");
+ return (0);
+ }else{
+ printf("error \n");
+ return (-1);
+ }
+}
+
+
+
+
+int test_priorty_queue(void){
+ CGenNode * node;
+ std::priority_queue<CGenNode *, std::vector<CGenNode *>,CGenNodeCompare> p_queue;
+ int i;
+ for (i=0; i<10; i++) {
+ node = new CGenNode();
+ printf(" +%x \n",node);
+ node->m_flow_id = 10-i;
+ node->m_pkt_info = (CFlowPktInfo *)(uintptr_t)i;
+ node->m_time = (double)i+0.1;
+ p_queue.push(node);
+ }
+ while (!p_queue.empty()) {
+ node = p_queue.top();
+ printf(" -->%x \n",node);
+ //node->Dump(stdout);
+ p_queue.pop();
+ //delete node;
+ }
+ return (0);
+}
+
+
+#if 0
+#ifdef WIN32
+
+int test_rate(){
+ int i;
+ CBwMeasure m;
+ uint64_t cnt=0;
+ for (i=0; i<10; i++) {
+ Sleep(100);
+ cnt+=10000;
+ printf (" %f \n",m.add(cnt));
+ }
+ return (0);
+}
+#endif
+#endif
+
+
+
+
+void histogram_test(){
+ CTimeHistogram t;
+ t.Create();
+ t.Add(0.0001);
+ t.Add(0.0002);
+ t.Add(0.0003);
+ int i;
+ for (i=0; i<100;i++) {
+ t.Add(1.0/1000000.0);
+ }
+ t.Dump(stdout);
+ t.Delete();
+}
+
+
+
+
+int test_human_p(){
+ printf ("%s \n",double_to_human_str(1024.0*1024.0,"Byte",KBYE_1024).c_str());
+ printf ("%s \n",double_to_human_str(1.0,"Byte",KBYE_1024).c_str());
+ printf ("%s \n",double_to_human_str(-3000.0,"Byte",KBYE_1024).c_str());
+ printf ("%s \n",double_to_human_str(-3000000.0,"Byte",KBYE_1024).c_str());
+ printf ("%s \n",double_to_human_str(-30000000.0,"Byte",KBYE_1024).c_str());
+ return (0);
+}
+
+
+
+static bool was_init=false;
+
+void gtest_init_once(){
+
+ if ( !was_init ){
+ CGlobalInfo::init_pools(1000);
+ time_init();
+ was_init=true;
+ }
+}
+
+
+
+#define EXPECT_EQ_UINT32(a,b) EXPECT_EQ((uint32_t)(a),(uint32_t)(b))
+
+
+class CTestBasic {
+
+public:
+ CTestBasic(){
+ m_threads=1;
+ m_time_diff=0.001;
+ m_req_ports=0;
+ m_dump_json=false;
+ }
+
+ bool init(void){
+
+ uint16 * ports;
+ CTupleBase tuple;
+
+ CErfIF erf_vif;
+
+
+ fl.Create();
+ m_saved_packet_padd_offset=0;
+
+ fl.load_from_yaml(CGlobalInfo::m_options.cfg_file,m_threads);
+ fl.generate_p_thread_info(m_threads);
+
+ CFlowGenListPerThread * lpt;
+
+ fl.m_threads_info[0]->set_vif(&erf_vif);
+
+
+ CErfCmp cmp;
+ cmp.dump=1;
+
+ bool res=true;
+
+
+ int i;
+ for (i=0; i<m_threads; i++) {
+ lpt=fl.m_threads_info[i];
+
+ CFlowPktInfo * pkt=lpt->m_cap_gen[0]->m_flow_info->GetPacket(0);
+ m_saved_packet_padd_offset =pkt->m_pkt_indication.m_packet_padding;
+
+ char buf[100];
+ char buf_ex[100];
+ sprintf(buf,"%s-%d.erf",CGlobalInfo::m_options.out_file.c_str(),i);
+ sprintf(buf_ex,"%s-%d-ex.erf",CGlobalInfo::m_options.out_file.c_str(),i);
+
+ if ( m_req_ports ){
+ /* generate from first template m_req_ports ports */
+ int i;
+ CTupleTemplateGeneratorSmart * lpg=&lpt->m_cap_gen[0]->tuple_gen;
+ ports = new uint16_t[m_req_ports];
+ lpg->GenerateTuple(tuple);
+ for (i=0 ; i<m_req_ports;i++) {
+ ports[i]=lpg->GenerateOneSourcePort();
+ }
+ }
+
+ lpt->generate_erf(buf,CGlobalInfo::m_options.preview);
+ lpt->m_node_gen.DumpHist(stdout);
+
+ cmp.d_sec = m_time_diff;
+ if ( cmp.compare(std::string(buf),std::string(buf_ex)) != true ) {
+ res=false;
+ }
+
+ }
+ if ( m_dump_json ){
+ printf(" dump json ...........\n");
+ std::string s;
+ fl.m_threads_info[0]->m_node_gen.dump_json(s);
+ printf(" %s \n",s.c_str());
+ }
+
+ if ( m_req_ports ){
+ int i;
+ fl.m_threads_info[0]->m_smart_gen.FreePort(tuple.getClient(),tuple.getClientPort());
+
+ for (i=0 ; i<m_req_ports;i++) {
+ fl.m_threads_info[0]->m_smart_gen.FreePort(tuple.getClient(),ports[i]);
+ }
+ delete []ports;
+ }
+
+ printf(" active %d \n", fl.m_threads_info[0]->m_smart_gen.ActiveSockets());
+ EXPECT_EQ_UINT32(fl.m_threads_info[0]->m_smart_gen.ActiveSockets(),0);
+ fl.Delete();
+ return (res);
+ }
+
+ uint16_t get_padd_offset_first_packet(){
+ return (m_saved_packet_padd_offset);
+
+ }
+
+
+
+public:
+ int m_req_ports;
+ int m_threads;
+ double m_time_diff;
+ bool m_dump_json;
+ uint16_t m_saved_packet_padd_offset;
+ CFlowGenList fl;
+};
+
+
+
+
+class basic : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ gtest_init_once();
+ }
+ virtual void TearDown() {
+ }
+public:
+};
+
+class cpu : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ gtest_init_once();
+ }
+ virtual void TearDown() {
+ }
+public:
+};
+
+
+
+TEST_F(basic, limit_single_pkt) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/limit_single_pkt.yaml";
+ po->out_file ="exp/limit_single_pkt";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+TEST_F(basic, limit_multi_pkt) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/limit_multi_pkt.yaml";
+ po->out_file ="exp/limit_multi_pkt";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+TEST_F(basic, imix) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/imix.yaml";
+ po->out_file ="exp/imix";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+
+TEST_F(basic, dns) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/dns.yaml";
+ po->out_file ="exp/dns";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+/* test -p function */
+TEST_F(basic, dns_flow_flip) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->preview.setClientServerFlowFlip(true);
+
+ po->cfg_file ="cap2/dns.yaml";
+ po->out_file ="exp/dns_p";
+ bool res=t1.init();
+ po->preview.setClientServerFlowFlip(false);
+
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+TEST_F(basic, dns_flip) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->preview.setClientServerFlip(true);
+
+ po->cfg_file ="cap2/dns.yaml";
+ po->out_file ="exp/dns_flip";
+ bool res=t1.init();
+ po->preview.setClientServerFlip(false);
+
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+TEST_F(basic, dns_e) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->preview.setClientServerFlowFlipAddr(true);
+
+ po->cfg_file ="cap2/dns.yaml";
+ po->out_file ="exp/dns_e";
+ bool res=t1.init();
+ po->preview.setClientServerFlowFlipAddr(false);
+
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+
+
+/* test the packet padding , must be valid for --rx-check to work */
+TEST_F(basic, dns_packet_padding_test) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/dns.yaml";
+ po->out_file ="exp/dns";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(t1.get_padd_offset_first_packet(),0);
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+
+TEST_F(basic, dns_ipv6) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->preview.set_ipv6_mode_enable(true);
+ po->cfg_file ="cap2/dns.yaml";
+ po->out_file ="exp/dns_ipv6";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+ EXPECT_EQ_UINT32(t1.get_padd_offset_first_packet(),0);
+ po->preview.set_ipv6_mode_enable(false);
+}
+
+TEST_F(basic, dns_json) {
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ t1.m_dump_json=true;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/dns.yaml";
+ po->out_file ="exp/dns";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+
+#if 0
+
+TEST_F(basic, dns_wlen) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/dns_wlen.yaml";
+ po->out_file ="exp/dns_wlen";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+TEST_F(basic, dns_wlen1) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/dns_wlen1.yaml";
+ po->out_file ="exp/dns_wlen1";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+TEST_F(basic, dns_wlen2) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/dns_wlen2.yaml";
+ po->out_file ="exp/dns_wlen2";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+
+
+TEST_F(basic, dns_one_server_2) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/dns_single_server.yaml";
+ po->out_file ="exp/dns_single_server";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+#endif
+
+TEST_F(basic, dns_one_server) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/dns_one_server.yaml";
+ po->out_file ="exp/dns_one_server";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+
+TEST_F(basic, sfr2) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+
+ po->preview.setVMode(0);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/sfr2.yaml";
+ po->out_file ="exp/sfr2";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+
+TEST_F(basic, sfr3) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(0);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/sfr3.yaml";
+ po->out_file ="exp/sfr3";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+
+TEST_F(basic, sfr4) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(0);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/sfr4.yaml";
+ po->out_file ="exp/sfr_4";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+
+TEST_F(basic, ipv6_convert) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.set_ipv6_mode_enable(true);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/imix.yaml";
+ po->out_file ="exp/imix_v6";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+ po->preview.set_ipv6_mode_enable(false);
+}
+
+TEST_F(basic, ipv6) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.set_ipv6_mode_enable(true);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/ipv6.yaml";
+ po->out_file ="exp/ipv6";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+ po->preview.set_ipv6_mode_enable(false);
+}
+
+TEST_F(basic, ipv4_vlan) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/ipv4_vlan.yaml";
+ po->out_file ="exp/ipv4_vlan";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+TEST_F(basic, ipv6_vlan) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.set_ipv6_mode_enable(true);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/ipv6_vlan.yaml";
+ po->out_file ="exp/ipv6_vlan";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+ po->preview.set_ipv6_mode_enable(false);
+}
+
+
+/* exacly like cap file */
+TEST_F(basic, test_pcap_mode1) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/test_pcap_mode1.yaml";
+ po->out_file ="exp/pcap_mode1";
+ t1.m_time_diff = 0.000005; // 5 nsec
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+
+/* check override the low IPG */
+TEST_F(basic, test_pcap_mode2) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/test_pcap_mode2.yaml";
+ po->out_file ="exp/pcap_mode2";
+ t1.m_time_diff = 0.000005; // 5 nsec
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+
+
+
+
+TEST_F(basic, latency1) {
+ CLatencyPktInfo l;
+ l.Create();
+
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+
+ uint8_t mac[]={0,0,0,1,0,0};
+
+ CErfIF erf_vif;
+ erf_vif.set_review_mode(&CGlobalInfo::m_options.preview);
+
+ erf_vif.open_file("exp/sctp.erf");
+
+
+ mac[0]=0;
+ mac[1]=0;
+ mac[2]=0;
+ mac[3]=1;
+ mac[4]=0;
+ mac[5]=0;
+
+
+ l.set_ip(0x10000000,0x20000000,0x01000000);
+
+ int i;
+ /* simulate 8 ports */
+ for (i=0;i<8; i++) {
+ rte_mbuf_t * m=l.generate_pkt(i);
+ erf_vif.send_node(l.getNode());
+ rte_pktmbuf_free(m);
+ }
+
+ erf_vif.close_file();
+
+
+ l.Delete();
+
+ CErfCmp cmp;
+ cmp.dump=1;
+
+ bool res=true;
+
+ if ( cmp.compare("exp/sctp.erf","exp/sctp-ex.erf") != true ) {
+ res=false;
+ }
+ EXPECT_EQ_UINT32((uint32_t)res?1:0, (uint32_t)1)<< "pass";
+}
+
+
+
+TEST_F(basic, latency2) {
+ CLatencyPktInfo l;
+ CCPortLatency port0;
+ l.Create();
+ port0.Create(0,0,l.get_payload_offset(),l.get_pkt_size(),0);
+
+
+ uint8_t mac[]={0,0,0,1,0,0};
+
+ mac[0]=0;
+ mac[1]=0;
+ mac[2]=0;
+ mac[3]=1;
+ mac[4]=0;
+ mac[5]=0;
+
+
+ l.set_ip(0x01000000,0x02000000,0x01000000);
+
+
+ int i;
+ for (i=0; i<100; i++) {
+ uint8_t *p;
+ rte_mbuf_t * m=l.generate_pkt(0);
+ p=rte_pktmbuf_mtod(m, uint8_t*);
+ //utl_DumpBuffer(stdout,p,l.get_pkt_size(),0);
+
+ port0.update_packet(m);
+
+ p=rte_pktmbuf_mtod(m, uint8_t*);
+ //utl_DumpBuffer(stdout,p,l.get_pkt_size(),0);
+ //printf("offset is : %d \n",l.get_payload_offset());
+
+ CRx_check_header * rx_p;
+ bool res=port0.check_packet(m,rx_p);
+ EXPECT_EQ_UINT32((uint32_t)res?1:0, (uint32_t)1)<< "pass";
+ if (!res ) {
+ printf(" ERROR \n");
+ }
+ rte_pktmbuf_free(m);
+ }
+ port0.DumpCounters(stdout);
+ EXPECT_EQ_UINT32(port0.m_pkt_ok, (uint32_t)100)<< "pass";
+
+ port0.Delete();
+ l.Delete();
+}
+
+
+TEST_F(basic, latency3) {
+ CLatencyPktInfo l;
+ CCPortLatency port0;
+ l.Create();
+ port0.Create(0,0,l.get_payload_offset(),l.get_pkt_size(),0);
+
+
+ uint8_t mac[]={0,0,0,1,0,0};
+
+
+ mac[0]=0;
+ mac[1]=0;
+ mac[2]=0;
+ mac[3]=1;
+ mac[4]=0;
+ mac[5]=0;
+
+
+ l.set_ip(0x01000000,0x02000000,0x01000000);
+
+ uint8_t *p;
+ rte_mbuf_t * m=l.generate_pkt(0);
+ port0.update_packet(m);
+ p=rte_pktmbuf_mtod(m, uint8_t*);
+ memset(p,0,l.get_pkt_size());
+
+ CRx_check_header * rx_p;
+ bool res=port0.check_packet(m,rx_p);
+ EXPECT_EQ_UINT32((uint32_t)res?0:1, (uint32_t)1)<< "pass";
+ if (!res ) {
+ printf(" OK \n");
+ }
+ rte_pktmbuf_free(m);
+ EXPECT_EQ_UINT32(port0.m_unsup_prot, (uint32_t)1)<< "pass";
+
+ port0.Delete();
+ l.Delete();
+}
+
+
+
+
+class CDummyLatencyHWBase : public CPortLatencyHWBase {
+public:
+ CDummyLatencyHWBase(){
+ m_queue=0;
+ m_port_id=0;
+ }
+
+ virtual int tx(rte_mbuf_t * m){
+ assert(m_queue==0);
+ //printf(" tx on port %d \n",m_port_id);
+ // utl_DumpBuffer(stdout,rte_pktmbuf_mtod(m, uint8_t*),rte_pktmbuf_pkt_len(m),0);
+ m_queue=m;
+ return (0);
+ }
+
+ virtual rte_mbuf_t * rx(){
+ //printf(" rx on port %d \n",m_port_id);
+ rte_mbuf_t * m=0;
+ if (m_queue ) {
+ m=m_queue;
+ m_queue=0;
+ }
+
+ /*if ( m ){
+ utl_DumpBuffer(stdout,rte_pktmbuf_mtod(m , uint8_t*),rte_pktmbuf_pkt_len(m ),0);
+ } */
+ return ( m );
+ }
+
+ virtual uint16_t rx_burst(struct rte_mbuf **rx_pkts,
+ uint16_t nb_pkts){
+ //printf(" rx on port %d \n",m_port_id);
+ rte_mbuf_t * m=rx();
+ if (m) {
+ rx_pkts[0]=m;
+ return (1);
+ }else{
+ return (0);
+ }
+ }
+
+
+private:
+ rte_mbuf_t * m_queue;
+public:
+ uint8_t m_port_id;
+};
+
+
+
+TEST_F(basic, latency4) {
+
+ uint8_t mac[]={0,0,0,1,0,0};
+
+ mac[0]=0;
+ mac[1]=0;
+ mac[2]=0;
+ mac[3]=1;
+ mac[4]=0;
+ mac[5]=0;
+
+
+ CLatencyManager mg;
+ CLatencyManagerCfg cfg;
+ CDummyLatencyHWBase dports[MAX_LATENCY_PORTS];
+ cfg.m_cps =10;
+ cfg.m_max_ports=4;
+ int i;
+ for (i=0; i<MAX_LATENCY_PORTS; i++) {
+ dports[i].m_port_id=i;
+ cfg.m_ports[i] = &dports[i];
+ }
+
+ mg.Create(&cfg);
+
+ printf(" before sending \n");
+ mg.Dump(stdout);
+ std::string json;
+ mg.dump_json_v2(json);
+ printf(" %s \n",json.c_str());
+
+
+ EXPECT_EQ_UINT32(mg.is_active()?1:0, (uint32_t)0)<< "pass";
+
+ mg.start(8);
+ mg.stop();
+ mg.Dump(stdout);
+ mg.DumpShort(stdout);
+ mg.dump_json_v2(json);
+ printf(" %s \n",json.c_str());
+
+ mg.Delete();
+}
+
+
+TEST_F(basic, hist1) {
+
+ CTimeHistogram hist1;
+
+ dsec_t dusec=1.0/1000000.0;
+
+ hist1.Create();
+ hist1.Add(dusec);
+ hist1.Add(2.0*dusec);
+ hist1.Add(11.0*dusec);
+ hist1.Add(110.0*dusec);
+ hist1.Add(1110.0*dusec);
+ hist1.Add(10110.0*dusec);
+ hist1.Add(40110.0*dusec);
+ hist1.Add(400110.0*dusec);
+ hist1.Dump(stdout);
+ hist1.Delete();
+}
+
+
+
+TEST_F(basic, rtsp1) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/rtsp_short1.yaml";
+ po->out_file ="exp/rtsp_short1";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+TEST_F(basic, rtsp2) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/rtsp_short2.yaml";
+ po->out_file ="exp/rtsp_short2";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+TEST_F(basic, rtsp3) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/rtsp_short3.yaml";
+ po->out_file ="exp/rtsp_short3";
+ t1.m_req_ports = 32000;
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+
+TEST_F(basic, rtsp1_ipv6) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.set_ipv6_mode_enable(true);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/rtsp_short1.yaml";
+ po->out_file ="exp/rtsp_short1_v6";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+ po->preview.set_ipv6_mode_enable(false);
+}
+
+TEST_F(basic, rtsp2_ipv6) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.set_ipv6_mode_enable(true);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/rtsp_short2.yaml";
+ po->out_file ="exp/rtsp_short2_v6";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+ po->preview.set_ipv6_mode_enable(false);
+}
+
+TEST_F(basic, rtsp3_ipv6) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.set_ipv6_mode_enable(true);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/rtsp_short3.yaml";
+ po->out_file ="exp/rtsp_short3_v6";
+ t1.m_req_ports = 32000;
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+ po->preview.set_ipv6_mode_enable(false);
+}
+
+
+TEST_F(basic, sip1) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/sip_short1.yaml";
+ po->out_file ="exp/sip_short1";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+
+TEST_F(basic, sip2) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/sip_short2.yaml";
+ po->out_file ="exp/sip_short2";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+TEST_F(basic, sip3) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/sip_short2.yaml";
+ po->out_file ="exp/sip_short3";
+ t1.m_req_ports = 32000;
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+
+TEST_F(basic, sip1_ipv6) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.set_ipv6_mode_enable(true);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/sip_short1.yaml";
+ po->out_file ="exp/sip_short1_v6";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+ po->preview.set_ipv6_mode_enable(false);
+}
+
+
+TEST_F(basic, sip2_ipv6) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.set_ipv6_mode_enable(true);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/sip_short2.yaml";
+ po->out_file ="exp/sip_short2_v6";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+ po->preview.set_ipv6_mode_enable(false);
+}
+
+TEST_F(basic, sip3_ipv6) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.set_ipv6_mode_enable(true);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/sip_short2.yaml";
+ po->out_file ="exp/sip_short3_v6";
+ t1.m_req_ports = 32000;
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+ po->preview.set_ipv6_mode_enable(false);
+}
+
+
+TEST_F(basic, dyn1) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/dyn_pyld1.yaml";
+ po->out_file ="exp/dyn_pyld1";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+TEST_F(basic, http1) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/http_plugin.yaml";
+ po->out_file ="exp/http_plugin";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+}
+
+TEST_F(basic, http1_ipv6) {
+
+ CTestBasic t1;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(3);
+ po->preview.set_ipv6_mode_enable(true);
+ po->preview.setFileWrite(true);
+ po->cfg_file ="cap2/http_plugin.yaml";
+ po->out_file ="exp/http_plugin_v6";
+ bool res=t1.init();
+ EXPECT_EQ_UINT32(1, res?1:0)<< "pass";
+ po->preview.set_ipv6_mode_enable(false);
+}
+
+
+
+void delay(int msec);
+
+
+TEST_F(cpu, cpu1) {
+ CCpuUtlDp cpu_dp;
+ CCpuUtlCp cpu_cp;
+ cpu_cp.Create(&cpu_dp);
+ int i;
+ for (i=0; i<5;i++) {
+ cpu_cp.Update();
+ double c=cpu_cp.GetVal();
+ printf (" %f \n",c);
+ EXPECT_EQ(c,(double)0.0);
+
+ delay(100);
+ }
+
+ cpu_cp.Delete();
+}
+
+TEST_F(cpu, cpu2) {
+ CCpuUtlDp cpu_dp;
+ CCpuUtlCp cpu_cp;
+ cpu_cp.Create(&cpu_dp);
+ int i;
+ for (i=0; i<100;i++) {
+ cpu_dp.start_work();
+ cpu_cp.Update();
+ double c1 = cpu_cp.GetVal();
+ printf(" cpu %2.0f \n",c1);
+ if (i>50) {
+ int s=( c1<80 && c1>30)?1:0;
+ EXPECT_EQ(s,1);
+ }
+ delay(1);
+ if ((i%2)==1) {
+ cpu_dp.commit();
+ }else{
+ cpu_dp.revert();
+ }
+ }
+
+ cpu_cp.Delete();
+}
+
+#if 0
+TEST_F(cpu, cpu3) {
+ CCpuUtlDp cpu_dp;
+ CCpuUtlCp cpu_cp;
+ cpu_cp.Create(&cpu_dp);
+ int i;
+ for (i=0; i<200;i++) {
+ cpu_dp.start_work();
+ if (i%10==0) {
+ cpu_cp.Update();
+ }
+ double c1 = cpu_cp.GetVal();
+ if (i>150) {
+ printf(" cpu %2.0f \n",c1);
+ int s=( c1<11 && c1>8)?1:0;
+ EXPECT_EQ(s,1);
+ }
+ delay(1);
+ if ((i%10)==1) {
+ cpu_dp.commit();
+ }else{
+ cpu_dp.revert();
+ }
+ }
+ cpu_cp.Delete();
+}
+#endif
+
+
+class timerwl : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ gtest_init_once();
+ }
+ virtual void TearDown() {
+ }
+public:
+};
+
+
+
+void flow_callback(CFlowTimerHandle * timer_handle);
+
+class CTestFlow {
+public:
+ CTestFlow(){
+ flow_id = 0;
+ m_timer_handle.m_callback=flow_callback;
+ m_timer_handle.m_object = (void *)this;
+ m_timer_handle.m_id = 0x1234;
+ }
+
+ uint32_t flow_id;
+ CFlowTimerHandle m_timer_handle;
+public:
+ void OnTimeOut(){
+ printf(" timeout %d \n",flow_id);
+ }
+};
+
+void flow_callback(CFlowTimerHandle * t){
+ CTestFlow * lp=(CTestFlow *)t->m_object;
+ assert(lp);
+ assert(t->m_id==0x1234);
+ lp->OnTimeOut();
+}
+
+
+TEST_F(timerwl, tw1) {
+ CTimerWheel my_tw;
+
+ CTestFlow f1;
+ CTestFlow f2;
+ CTestFlow f3;
+ CTestFlow f4;
+
+ f1.flow_id=1;
+ f2.flow_id=2;
+ f3.flow_id=3;
+ f4.flow_id=4;
+ double time;
+ EXPECT_EQ(my_tw.peek_top_time(time),false);
+ my_tw.restart_timer(&f1.m_timer_handle,10.0);
+ my_tw.restart_timer(&f2.m_timer_handle,5.0);
+ my_tw.restart_timer(&f3.m_timer_handle,1.0);
+ EXPECT_EQ(my_tw.peek_top_time(time),true);
+ printf(" time %f \n",time);
+ EXPECT_EQ(time ,1.0);
+
+ EXPECT_EQ(my_tw.peek_top_time(time),true);
+ printf(" time %f \n",time);
+ EXPECT_EQ(time ,1.0);
+
+ EXPECT_EQ(my_tw.peek_top_time(time),true);
+ printf(" time %f \n",time);
+ EXPECT_EQ(time ,1.0);
+
+ EXPECT_EQ(my_tw.handle(),true);
+
+ EXPECT_EQ(my_tw.peek_top_time(time),true);
+ printf(" time %f \n",time);
+ EXPECT_EQ(time ,5.0);
+
+ EXPECT_EQ(my_tw.handle(),true);
+
+ EXPECT_EQ(my_tw.peek_top_time(time),true);
+ printf(" time %f \n",time);
+ EXPECT_EQ(time ,10.0);
+
+ EXPECT_EQ(my_tw.handle(),true);
+
+}
+
+TEST_F(timerwl, tw2) {
+ CTimerWheel my_tw;
+
+ double mytime=0.1;
+ int i;
+ CTestFlow * af[100];
+
+ for (i=0; i<100; i++) {
+ CTestFlow * f=new CTestFlow();
+ af[i]=f;
+ f->flow_id=i;
+ my_tw.restart_timer(&f->m_timer_handle,mytime+10.0);
+ }
+ EXPECT_EQ(my_tw.m_st_alloc-my_tw.m_st_free,100);
+
+ my_tw.try_handle_events(mytime);
+
+ EXPECT_EQ(my_tw.m_st_alloc-my_tw.m_st_free,100);
+
+ for (i=0; i<100; i++) {
+ CTestFlow * f=af[i];
+ my_tw.stop_timer(&f->m_timer_handle);
+ }
+ EXPECT_EQ(my_tw.m_st_alloc-my_tw.m_st_free,100);
+
+ my_tw.try_handle_events(mytime);
+
+ /* expect to free all the object */
+ EXPECT_EQ(my_tw.m_st_alloc-my_tw.m_st_free,0);
+
+}
+
+TEST_F(timerwl, check_stop_timer) {
+
+ CTimerWheel my_tw;
+
+
+ CTestFlow f1;
+ CTestFlow f2;
+ CTestFlow f3;
+ CTestFlow f4;
+
+ f1.flow_id=1;
+ f2.flow_id=2;
+ f3.flow_id=3;
+ f4.flow_id=4;
+ double time;
+ assert(my_tw.peek_top_time(time)==false);
+ my_tw.restart_timer(&f1.m_timer_handle,10.0);
+ my_tw.restart_timer(&f2.m_timer_handle,5.0);
+ my_tw.restart_timer(&f3.m_timer_handle,1.0);
+ my_tw.stop_timer(&f1.m_timer_handle);
+
+ assert(my_tw.peek_top_time(time)==true);
+ printf(" time %f \n",time);
+ EXPECT_EQ(time ,1.0);
+
+ assert(my_tw.peek_top_time(time)==true);
+ printf(" time %f \n",time);
+ EXPECT_EQ(time ,1.0);
+
+ assert(my_tw.peek_top_time(time)==true);
+ printf(" time %f \n",time);
+ EXPECT_EQ(time ,1.0);
+
+ assert(my_tw.handle());
+
+ assert(my_tw.peek_top_time(time)==true);
+ printf(" time %f \n",time);
+ EXPECT_EQ(time ,5.0);
+
+
+ assert(my_tw.handle());
+
+ EXPECT_EQ(my_tw.peek_top_time(time) ,false);
+ my_tw.Dump(stdout);
+}
+
+
+static int many_timers_flow_id=0;
+
+void many_timers_flow_callback(CFlowTimerHandle * t){
+ CTestFlow * lp=(CTestFlow *)t->m_object;
+ assert(lp);
+ assert(t->m_id==0x1234);
+ assert(many_timers_flow_id==lp->flow_id);
+ many_timers_flow_id--;
+}
+
+
+TEST_F(timerwl, many_timers) {
+
+ CTimerWheel my_tw;
+
+ int i;
+ for (i=0; i<100; i++) {
+ CTestFlow * f= new CTestFlow();
+ f->m_timer_handle.m_callback=many_timers_flow_callback;
+ f->flow_id=(uint32_t)i;
+ my_tw.restart_timer(&f->m_timer_handle,100.0-(double)i);
+ }
+ many_timers_flow_id=99;
+
+ double time;
+ double ex_time=1.0;
+ while (true) {
+ if ( my_tw.peek_top_time(time) ){
+ assert(time==ex_time);
+ ex_time+=1.0;
+ assert(my_tw.handle());
+ }
+ else{
+ break;
+ }
+ }
+
+ my_tw.Dump(stdout);
+
+ EXPECT_EQ(my_tw.m_st_handle ,100);
+ EXPECT_EQ(my_tw.m_st_alloc ,100);
+ EXPECT_EQ(my_tw.m_st_free ,100);
+ EXPECT_EQ(my_tw.m_st_start ,100);
+
+}
+
+void many_timers_stop_flow_callback(CFlowTimerHandle * t){
+ CTestFlow * lp=(CTestFlow *)t->m_object;
+ assert(lp);
+ assert(t->m_id==0x1234);
+ assert(0);
+}
+
+TEST_F(timerwl, many_timers_with_stop) {
+ CTimerWheel my_tw;
+
+ int i;
+ for (i=0; i<100; i++) {
+ CTestFlow * f= new CTestFlow();
+ f->m_timer_handle.m_callback=many_timers_stop_flow_callback;
+ f->flow_id=(uint32_t)i;
+ my_tw.restart_timer(&f->m_timer_handle, 500.0 - (double)i);
+ my_tw.restart_timer(&f->m_timer_handle, 1000.0 - (double)i);
+ my_tw.restart_timer(&f->m_timer_handle, 100.0 - (double)i);
+ my_tw.stop_timer(&f->m_timer_handle);
+ }
+
+ double time;
+ while (true) {
+ if ( my_tw.peek_top_time(time) ){
+ assert(0);
+ assert(my_tw.handle());
+ }
+ else{
+ break;
+ }
+ }
+
+ my_tw.Dump(stdout);
+
+
+ EXPECT_EQ(my_tw.m_st_handle ,0);
+ EXPECT_EQ(my_tw.m_st_alloc-my_tw.m_st_free ,0);
+ EXPECT_EQ(my_tw.m_st_start ,300);
+}
+
+
+//////////////////////////////////////////////
+class rx_check : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ gtest_init_once();
+ m_rx_check.Create();
+
+ }
+ virtual void TearDown() {
+ m_rx_check.Delete();
+ }
+public:
+ RxCheckManager m_rx_check;
+};
+
+
+TEST_F(rx_check, rx_check_normal) {
+ int i;
+
+ for (i=0; i<10; i++) {
+ CRx_check_header rxh;
+ rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
+ rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
+ rxh.m_time_stamp=0;
+ rxh.m_magic=RX_CHECK_MAGIC;
+ rxh.m_aging_sec=10;
+ rxh.m_pkt_id=i;
+ rxh.m_flow_size=10;
+
+ rxh.m_flow_id=7;
+ rxh.set_dir(0);
+ rxh.set_both_dir(0);
+
+ m_rx_check.handle_packet(&rxh);
+ }
+
+ EXPECT_EQ(m_rx_check.m_stats.get_total_err(),0);
+ EXPECT_EQ(m_rx_check.m_stats.m_add,1);
+ EXPECT_EQ(m_rx_check.m_stats.m_remove,1);
+ m_rx_check.Dump(stdout);
+}
+
+
+TEST_F(rx_check, rx_check_drop) {
+
+ int i;
+
+ for (i=0; i<10; i++) {
+ CRx_check_header rxh;
+ rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
+ rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
+ rxh.m_time_stamp=0;
+ rxh.m_magic=RX_CHECK_MAGIC;
+ rxh.m_aging_sec=10;
+
+ if (i==4) {
+ /* drop packet 4 */
+ continue;
+ }
+ rxh.m_pkt_id=i;
+
+ rxh.m_flow_size=10;
+
+ rxh.set_dir(0);
+ rxh.set_both_dir(0);
+
+ rxh.m_flow_id=7;
+
+ rxh.m_flags=0;
+ m_rx_check.handle_packet(&rxh);
+ }
+ m_rx_check.tw_drain();
+ EXPECT_EQ(m_rx_check.m_stats.m_err_oo_late,1);
+ EXPECT_EQ(m_rx_check.m_stats.m_add,1);
+ EXPECT_EQ(m_rx_check.m_stats.m_remove,1);
+ m_rx_check.Dump(stdout);
+}
+
+TEST_F(rx_check, rx_check_ooo) {
+
+ m_rx_check.Create();
+ int i;
+
+ for (i=0; i<10; i++) {
+ CRx_check_header rxh;
+ rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
+ rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
+ rxh.m_time_stamp=0;
+ rxh.m_magic=RX_CHECK_MAGIC;
+ rxh.m_aging_sec=10;
+
+ rxh.set_dir(0);
+ rxh.set_both_dir(0);
+
+
+ /* out of order */
+ if (i==4) {
+ rxh.m_pkt_id=5;
+ }else{
+ if (i==5) {
+ rxh.m_pkt_id=4;
+ }else{
+ rxh.m_pkt_id=i;
+ }
+ }
+
+ rxh.m_flow_size=10;
+
+ rxh.m_flow_id=7;
+
+ rxh.m_flags=0;
+ m_rx_check.handle_packet(&rxh);
+ }
+ m_rx_check.tw_drain();
+ EXPECT_EQ(m_rx_check.m_stats.m_err_oo_early,1);
+ EXPECT_EQ(m_rx_check.m_stats.m_err_oo_late,2);
+
+ m_rx_check.Dump(stdout);
+}
+
+
+TEST_F(rx_check, rx_check_ooo_1) {
+ int i;
+
+ for (i=0; i<10; i++) {
+ CRx_check_header rxh;
+ rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
+ rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
+ rxh.m_time_stamp=0;
+ rxh.set_dir(0);
+ rxh.set_both_dir(0);
+
+ rxh.m_magic=RX_CHECK_MAGIC;
+ rxh.m_aging_sec=10;
+
+ /* out of order */
+ if (i==4) {
+ rxh.m_pkt_id=56565;
+ }else{
+ if (i==5) {
+ rxh.m_pkt_id=4;
+ }else{
+ rxh.m_pkt_id=i;
+ }
+ }
+ rxh.m_flow_size=10;
+ rxh.m_flow_id=7;
+ rxh.m_flags=0;
+ m_rx_check.handle_packet(&rxh);
+ }
+ m_rx_check.tw_drain();
+ EXPECT_EQ(m_rx_check.m_stats.m_err_wrong_pkt_id,1);
+ EXPECT_EQ(m_rx_check.m_stats.m_err_oo_late,1);
+
+ m_rx_check.Dump(stdout);
+}
+
+// start without first packet ( not FIF */
+TEST_F(rx_check, rx_check_ooo_2) {
+ int i;
+
+ for (i=0; i<10; i++) {
+ CRx_check_header rxh;
+ rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
+ rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
+ rxh.m_time_stamp=0;
+ rxh.m_magic=RX_CHECK_MAGIC;
+ rxh.m_aging_sec=10;
+
+ /* out of order */
+ rxh.set_dir(0);
+ rxh.set_both_dir(0);
+
+
+ if (i==0) {
+ rxh.m_pkt_id=7;
+ }else{
+ if (i==7) {
+ rxh.m_pkt_id=0;
+ }else{
+ rxh.m_pkt_id=i;
+ }
+ }
+
+ rxh.m_flow_size=10;
+ rxh.m_flow_id=7;
+ rxh.m_flags=0;
+ m_rx_check.handle_packet(&rxh);
+ }
+ m_rx_check.tw_drain();
+ EXPECT_EQ(m_rx_check.m_stats.m_err_open_with_no_fif_pkt,1);
+ EXPECT_EQ(m_rx_check.m_stats. m_err_oo_late,1);
+ m_rx_check.Dump(stdout);
+}
+
+
+TEST_F(rx_check, rx_check_normal_two_dir) {
+ int i;
+
+ for (i=0; i<10; i++) {
+ CRx_check_header rxh;
+ rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
+ rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
+ rxh.m_time_stamp=0;
+ rxh.m_magic=RX_CHECK_MAGIC;
+ rxh.m_aging_sec=10;
+
+ rxh.m_pkt_id=i;
+ rxh.m_flow_size=10;
+
+ rxh.m_flow_id=7;
+ rxh.set_dir(0);
+ rxh.set_both_dir(0);
+
+ m_rx_check.handle_packet(&rxh);
+ }
+
+ EXPECT_EQ(m_rx_check.m_stats.get_total_err(),0);
+ EXPECT_EQ(m_rx_check.m_stats.m_add,1);
+ EXPECT_EQ(m_rx_check.m_stats.m_remove,1);
+ m_rx_check.Dump(stdout);
+}
+
+
+
+TEST_F(rx_check, rx_check_normal_two_dir_fails) {
+ int i;
+
+ for (i=0; i<10; i++) {
+ CRx_check_header rxh;
+ rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
+ rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
+ rxh.m_time_stamp=0;
+ rxh.m_magic=RX_CHECK_MAGIC;
+ rxh.m_aging_sec=10;
+
+ rxh.m_pkt_id=i;
+ rxh.m_flow_size=10;
+
+ rxh.m_flow_id=7;
+ rxh.set_dir(0);
+ rxh.set_both_dir(1);
+
+ m_rx_check.handle_packet(&rxh);
+ }
+
+ EXPECT_EQ(m_rx_check.m_stats.get_total_err(),0);
+ EXPECT_EQ(m_rx_check.m_stats.m_add,1);
+ EXPECT_EQ(m_rx_check.m_stats.m_remove,0);
+ m_rx_check.Dump(stdout);
+}
+
+TEST_F(rx_check, rx_check_normal_two_dir_ok) {
+ int i;
+
+ CRx_check_header rxh;
+ rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
+ rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
+ rxh.m_time_stamp=0;
+ rxh.m_magic=RX_CHECK_MAGIC;
+ rxh.m_aging_sec=10;
+
+ rxh.set_both_dir(1);
+ rxh.m_flow_id=7;
+ rxh.m_flow_size=10;
+
+ for (i=0; i<10; i++) {
+ rxh.m_pkt_id=i;
+ printf(" first : %d \n",i);
+ rxh.set_dir(0);
+ m_rx_check.handle_packet(&rxh);
+ }
+
+ for (i=0; i<10; i++) {
+ printf(" se : %d \n",i);
+ rxh.m_pkt_id=i;
+ rxh.set_dir(1);
+ m_rx_check.handle_packet(&rxh);
+ }
+
+ EXPECT_EQ(m_rx_check.m_stats.get_total_err(),0);
+ EXPECT_EQ(m_rx_check.m_stats.m_add,1);
+ EXPECT_EQ(m_rx_check.m_stats.m_remove,1);
+ m_rx_check.Dump(stdout);
+}
+
+TEST_F(rx_check, rx_check_normal_one_pkt_one_dir) {
+ int i;
+
+ CRx_check_header rxh;
+ rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
+ rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
+ rxh.m_time_stamp=0;
+ rxh.m_magic=RX_CHECK_MAGIC;
+ rxh.m_aging_sec=10;
+
+ rxh.set_both_dir(1);
+ rxh.m_flow_id=7;
+ rxh.m_flow_size=1;
+
+ for (i=0; i<1; i++) {
+ rxh.m_pkt_id=i;
+ printf(" first : %d \n",i);
+ rxh.set_dir(0);
+ m_rx_check.handle_packet(&rxh);
+ }
+ EXPECT_EQ(m_rx_check.m_stats.get_total_err(),0);
+ EXPECT_EQ(m_rx_check.m_stats.m_add,1);
+ EXPECT_EQ(m_rx_check.m_stats.m_remove,0);
+ m_rx_check.Dump(stdout);
+}
+
+TEST_F(rx_check, rx_check_normal_one_pkt_one_dir_0) {
+ int i;
+
+ CRx_check_header rxh;
+ rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
+ rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
+ rxh.m_time_stamp=0;
+ rxh.m_magic=RX_CHECK_MAGIC;
+ rxh.m_aging_sec=10;
+
+ rxh.set_both_dir(0);
+ rxh.m_flow_id=7;
+ rxh.m_flow_size=1;
+
+ for (i=0; i<1; i++) {
+ rxh.m_pkt_id=i;
+ rxh.set_dir(0);
+ m_rx_check.handle_packet(&rxh);
+ }
+ EXPECT_EQ(m_rx_check.m_stats.get_total_err(),0);
+ EXPECT_EQ(m_rx_check.m_stats.m_add,1);
+ EXPECT_EQ(m_rx_check.m_stats.m_remove,1);
+ m_rx_check.Dump(stdout);
+}
+
+TEST_F(rx_check, rx_check_normal_one_pkt_two_dir_0) {
+ int i;
+
+ CRx_check_header rxh;
+ rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
+ rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
+ rxh.m_time_stamp=0;
+ rxh.m_magic=RX_CHECK_MAGIC;
+ rxh.m_aging_sec=10;
+
+ rxh.set_both_dir(1);
+ rxh.m_flow_id=7;
+ rxh.m_flow_size=1;
+
+ for (i=0; i<1; i++) {
+ rxh.m_pkt_id=i;
+ rxh.set_dir(0);
+ m_rx_check.handle_packet(&rxh);
+ }
+
+ for (i=0; i<1; i++) {
+ rxh.m_pkt_id=i;
+ rxh.set_dir(1);
+ m_rx_check.handle_packet(&rxh);
+ }
+
+ EXPECT_EQ(m_rx_check.m_stats.get_total_err(),0);
+ EXPECT_EQ(m_rx_check.m_stats.m_add,1);
+ EXPECT_EQ(m_rx_check.m_stats.m_remove,1);
+ m_rx_check.Dump(stdout);
+}
+
+TEST_F(rx_check, rx_check_normal_one_pkt_two_dir_err1) {
+ int i;
+
+ CRx_check_header rxh;
+ rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
+ rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
+ rxh.m_time_stamp=0;
+ rxh.m_magic=RX_CHECK_MAGIC;
+ rxh.m_aging_sec=10;
+
+ rxh.set_both_dir(1);
+ rxh.m_flow_id=7;
+ rxh.m_flow_size=10;
+
+ for (i=0; i<10; i++) {
+ rxh.m_pkt_id=i;
+ rxh.set_dir(0);
+ m_rx_check.handle_packet(&rxh);
+ }
+
+ for (i=0; i<10; i++) {
+ if (i==0) {
+ rxh.m_pkt_id=7;
+ }else{
+ if (i==7) {
+ rxh.m_pkt_id=0;
+ }else{
+ rxh.m_pkt_id=i;
+ }
+ }
+
+ rxh.set_dir(1);
+ m_rx_check.handle_packet(&rxh);
+ }
+
+ EXPECT_EQ(m_rx_check.m_stats.m_err_oo_late,1);
+ EXPECT_EQ(m_rx_check.m_stats.m_err_fif_seen_twice,1);
+ EXPECT_EQ(m_rx_check.m_stats.m_add,1);
+ EXPECT_EQ(m_rx_check.m_stats.m_remove,0);
+ m_rx_check.Dump(stdout);
+}
+
+
+TEST_F(rx_check, rx_check_normal_two_dir_oo) {
+ int i;
+
+ CRx_check_header rxh;
+ rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
+ rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
+ rxh.m_time_stamp=0;
+ rxh.m_magic=RX_CHECK_MAGIC;
+ rxh.m_aging_sec=10;
+
+ rxh.set_both_dir(1);
+ rxh.m_flow_id=7;
+ rxh.m_flow_size=10;
+
+ for (i=0; i<10; i++) {
+ rxh.m_pkt_id=i;
+ rxh.set_dir(0);
+ m_rx_check.handle_packet(&rxh);
+ }
+
+ for (i=0; i<10; i++) {
+
+ if (i==4) {
+ rxh.m_pkt_id=5;
+ }else{
+ if (i==5) {
+ rxh.m_pkt_id=4;
+ }else{
+ rxh.m_pkt_id=i;
+ }
+ }
+
+
+ rxh.set_dir(1);
+ m_rx_check.handle_packet(&rxh);
+ }
+
+ EXPECT_EQ(m_rx_check.m_stats.m_err_oo_early,1);
+ EXPECT_EQ(m_rx_check.m_stats.m_err_oo_late,2);
+ EXPECT_EQ(m_rx_check.m_stats.m_add,1);
+ EXPECT_EQ(m_rx_check.m_stats.m_remove,0);
+ m_rx_check.Dump(stdout);
+}
+
+TEST_F(rx_check, rx_check_normal_aging) {
+ int i;
+
+ CRx_check_header rxh;
+ rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
+ rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
+ rxh.m_magic=RX_CHECK_MAGIC;
+ rxh.m_aging_sec=2;
+
+ rxh.set_both_dir(0);
+ rxh.m_flow_id=7;
+ rxh.m_flow_size=10;
+ rxh.m_template_id=13;
+
+ for (i=0; i<9; i++) {
+ rxh.m_time_stamp=(uint32_t)now_sec();
+ rxh.m_pkt_id=i;
+ rxh.set_dir(0);
+ rxh.m_pkt_id=i;
+ if (i<5) {
+ m_rx_check.m_cur_time = (now_sec()+10);
+ }
+ m_rx_check.tw_handle();
+ m_rx_check.handle_packet(&rxh);
+ }
+
+ EXPECT_EQ(m_rx_check.m_template_info[13].get_error_counter()>0?1:0,1);
+ EXPECT_EQ(m_rx_check.m_stats.m_err_aged,4);
+ EXPECT_EQ(m_rx_check.m_stats.m_err_open_with_no_fif_pkt,4 );
+ EXPECT_EQ(m_rx_check.m_stats.m_err_oo_late,1);
+
+ m_rx_check.Dump(stdout);
+}
+
+TEST_F(rx_check, rx_check_normal_no_aging) {
+ int i;
+
+ CRx_check_header rxh;
+ rxh.m_option_type=RX_CHECK_V4_OPT_TYPE;
+ rxh.m_option_len=RX_CHECK_V4_OPT_LEN;
+ rxh.m_magic=RX_CHECK_MAGIC;
+ rxh.m_aging_sec=10;
+
+ rxh.set_both_dir(0);
+ rxh.m_flow_id=7;
+ rxh.m_flow_size=10;
+
+ for (i=0; i<9; i++) {
+ rxh.m_time_stamp=(uint32_t)now_sec();
+ rxh.m_pkt_id=i;
+ rxh.set_dir(0);
+ rxh.m_pkt_id=i;
+ m_rx_check.tw_handle();
+ m_rx_check.handle_packet(&rxh);
+ }
+
+ EXPECT_EQ(m_rx_check.m_stats.get_total_err(),0);
+ EXPECT_EQ(m_rx_check.m_stats.m_add,1);
+ EXPECT_EQ(m_rx_check.m_stats.m_remove,0);
+}
+
+
+///////////////////////////////////////////////////////////////
+// check the generation of template and check sample of it
+
+
+class CRxCheckCallbackBase {
+public:
+ virtual void handle_packet(rte_mbuf * m)=0;
+ void * obj;
+};
+
+class CRxCheckIF : public CVirtualIF {
+
+public:
+ CRxCheckIF(){
+ m_callback=NULL;
+ m_raw=NULL;
+ m_one_dir=true;
+ m_store_pcfg=false;
+ }
+public:
+
+ virtual int open_file(std::string file_name){
+ m_raw = new CCapPktRaw();
+ assert(m_raw);
+ return (0);
+ }
+
+ virtual int close_file(void){
+ assert(m_raw);
+ m_raw->raw=0;
+ delete m_raw;
+ return (0);
+ }
+
+
+ /**
+ * send one packet
+ *
+ * @param node
+ *
+ * @return
+ */
+ virtual int send_node(CGenNode * node);
+
+
+
+ /**
+ * flush all pending packets into the stream
+ *
+ * @return
+ */
+ virtual int flush_tx_queue(void){
+ return (0);
+ }
+
+
+public:
+ bool m_one_dir;
+ bool m_store_pcfg;
+ CErfIF erf_vif;
+ CCapPktRaw * m_raw;
+ CRxCheckCallbackBase * m_callback;
+};
+
+
+int CRxCheckIF::send_node(CGenNode * node){
+
+ CFlowPktInfo * lp=node->m_pkt_info;
+ rte_mbuf_t * m=lp->generate_new_mbuf(node);
+
+ /* update mac addr dest/src 12 bytes */
+ uint8_t *p=(uint8_t *)m_raw->raw;
+ uint8_t p_id = node->m_pkt_info->m_pkt_indication.m_desc.IsInitSide()?0:1;
+ memcpy(p,CGlobalInfo::m_options.get_dst_src_mac_addr(p_id),12);
+
+ if ( unlikely( node->is_rx_check_enabled() ) ) {
+ lp->do_generate_new_mbuf_rxcheck(m,node,p_id,m_one_dir);
+ }
+
+ fill_pkt(m_raw,m);
+ CPktNsecTimeStamp t_c(node->m_time);
+ m_raw->time_nsec = t_c.m_time_nsec;
+ m_raw->time_sec = t_c.m_time_sec;
+ m_raw->setInterface(node->m_pkt_info->m_pkt_indication.m_desc.IsInitSide());
+
+ if (m_store_pcfg) {
+ erf_vif.write_pkt(m_raw);
+ }
+
+ if ((m_callback) && (node->is_rx_check_enabled()) ) {
+ m_callback->handle_packet(m);
+ }
+
+ // just free it
+ rte_pktmbuf_free(m);
+ return (0);
+}
+
+
+class CRxCheckBasic {
+
+public:
+ CRxCheckBasic(){
+ m_threads=1;
+ lpVf=0;
+ }
+
+ bool init(void){
+ CFlowGenList fl;
+ fl.Create();
+ fl.load_from_yaml(CGlobalInfo::m_options.cfg_file,m_threads);
+ CGlobalInfo::m_options.set_rxcheck_const_ts();
+
+ fl.generate_p_thread_info(m_threads);
+ CFlowGenListPerThread * lpt;
+ fl.m_threads_info[0]->set_vif(lpVf);
+ int i;
+ for (i=0; i<m_threads; i++) {
+ lpt=fl.m_threads_info[i];
+ lpt->generate_erf("t1",CGlobalInfo::m_options.preview);
+ }
+ fl.Delete();
+ return (true);
+ }
+
+public:
+ int m_threads;
+ CRxCheckIF * lpVf;
+};
+
+
+class CRxCheck1 : public CRxCheckCallbackBase {
+public:
+
+ virtual void handle_packet(rte_mbuf_t * m){
+ char *mp=rte_pktmbuf_mtod(m, char*);
+ CRx_check_header * rx_p;
+ rte_mbuf_t * m2 = m->next;
+ rx_p=(CRx_check_header *)rte_pktmbuf_mtod(m2, char*);
+ mg->handle_packet(rx_p);
+ //pkt->Dump(stdout,1);
+ }
+ RxCheckManager * mg;
+};
+
+
+class rx_check_system : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ gtest_init_once();
+
+ m_rx_check.m_callback=&m_callback;
+ m_callback.mg =&m_mg;
+ m_mg.Create();
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(0);
+ po->preview.setFileWrite(true);
+ po->preview.set_rx_check_enable(true);
+
+ }
+
+ virtual void TearDown() {
+ m_mg.Delete();
+ }
+public:
+ CRxCheckBasic m_rxcs;
+ CRxCheckIF m_rx_check;
+ CRxCheck1 m_callback;
+ RxCheckManager m_mg;
+
+};
+
+
+// check DNS yaml with sample of 1/2 check that there is no errors
+TEST_F(rx_check_system, rx_system1) {
+
+ m_rxcs.lpVf=&m_rx_check;
+ CParserOption * po =&CGlobalInfo::m_options;
+
+ po->m_rx_check_sampe=2; /* sample rate */
+ po->m_duration=100;
+ po->cfg_file ="cap2/dns.yaml";
+
+ m_rxcs.init();
+ m_mg.tw_drain();
+
+ m_mg.Dump(stdout);
+
+ EXPECT_EQ(m_mg.m_stats.get_total_err(),0);
+}
+
+// check DNS with rxcheck and write results out to capture file
+TEST_F(rx_check_system, rx_system1_dns) {
+
+ m_rxcs.lpVf=&m_rx_check;
+ CParserOption * po =&CGlobalInfo::m_options;
+
+ po->m_rx_check_sampe=1; /* sample rate */
+ po->m_duration=1;
+ po->cfg_file ="cap2/dns.yaml";
+ m_rx_check.m_store_pcfg=true;
+
+ m_rx_check.erf_vif.set_review_mode(&CGlobalInfo::m_options.preview);
+ m_rx_check.erf_vif.open_file("exp/dns_rxcheck.erf");
+
+ m_rxcs.init();
+ m_mg.tw_drain();
+ m_rx_check.erf_vif.close_file();
+
+ CErfCmp cmp;
+ cmp.dump=1;
+ EXPECT_EQ(cmp.compare("exp/dns_rxcheck.erf","exp/dns_rxcheck-ex.erf"),true);
+}
+
+// check DNS yaml with sample of 1/4 using IPv6 packets
+TEST_F(rx_check_system, rx_system1_ipv6) {
+
+ m_rxcs.lpVf=&m_rx_check;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.set_ipv6_mode_enable(true);
+
+ po->m_rx_check_sampe=4; /* sample rate */
+ po->m_duration=100;
+ po->cfg_file ="cap2/dns.yaml";
+
+ m_rxcs.init();
+ m_mg.tw_drain();
+
+ m_mg.Dump(stdout);
+
+ EXPECT_EQ(m_mg.m_stats.get_total_err(),0);
+ po->preview.set_ipv6_mode_enable(false);
+}
+
+// check DNS with rxcheck using IPv6 packets
+// and write results out to capture file
+TEST_F(rx_check_system, rx_system1_dns_ipv6) {
+
+ m_rxcs.lpVf=&m_rx_check;
+ CParserOption * po =&CGlobalInfo::m_options;
+
+ po->preview.set_ipv6_mode_enable(true);
+ po->m_rx_check_sampe=1; /* sample rate */
+ po->m_duration=1;
+ po->cfg_file ="cap2/dns.yaml";
+ m_rx_check.m_store_pcfg=true;
+
+ m_rx_check.erf_vif.set_review_mode(&CGlobalInfo::m_options.preview);
+ m_rx_check.erf_vif.open_file("exp/dns_ipv6_rxcheck.erf");
+
+ m_rxcs.init();
+ m_mg.tw_drain();
+ m_rx_check.erf_vif.close_file();
+
+ CErfCmp cmp;
+ cmp.dump=1;
+ EXPECT_EQ(cmp.compare("exp/dns_ipv6_rxcheck.erf","exp/dns_ipv6_rxcheck-ex.erf"),true);
+ po->preview.set_ipv6_mode_enable(false);
+}
+
+TEST_F(rx_check_system, rx_system2_plugin_one_dir) {
+
+ m_rxcs.lpVf=&m_rx_check;
+ CParserOption * po =&CGlobalInfo::m_options;
+
+ po->m_rx_check_sampe=2; /* sample rate */
+ po->m_duration=100;
+ po->cfg_file ="cap2/rtsp_short1.yaml";
+
+ m_rxcs.init();
+ m_mg.tw_drain();
+
+ m_mg.Dump(stdout);
+
+ EXPECT_EQ(m_mg.m_stats.get_total_err(),0);
+}
+
+// check HTTP with rxcheck and write results out to capture file
+TEST_F(rx_check_system, rx_system2_plugin) {
+
+ m_rxcs.lpVf=&m_rx_check;
+ CParserOption * po =&CGlobalInfo::m_options;
+
+ po->m_rx_check_sampe=1; /* sample rate */
+ po->m_duration=1;
+ po->cfg_file ="cap2/rtsp_short1.yaml";
+ m_rx_check.m_store_pcfg=true;
+
+ m_rx_check.erf_vif.set_review_mode(&CGlobalInfo::m_options.preview);
+ m_rx_check.erf_vif.open_file("exp/rtsp_short1_rxcheck.erf");
+
+ m_rxcs.init();
+ m_mg.tw_drain();
+ m_rx_check.erf_vif.close_file();
+
+ CErfCmp cmp;
+ cmp.dump=1;
+ EXPECT_EQ(cmp.compare("exp/rtsp_short1_rxcheck.erf","exp/rtsp_short1_rxcheck-ex.erf"),true);
+}
+
+// check DNS with rxcheck using IPv6 packets
+// and write results out to capture file
+TEST_F(rx_check_system, rx_system2_plugin_ipv6) {
+
+ m_rxcs.lpVf=&m_rx_check;
+ CParserOption * po =&CGlobalInfo::m_options;
+
+ po->preview.set_ipv6_mode_enable(true);
+ po->m_rx_check_sampe=1; /* sample rate */
+ po->m_duration=1;
+ po->cfg_file ="cap2/rtsp_short1.yaml";
+ m_rx_check.m_store_pcfg=true;
+
+ m_rx_check.erf_vif.set_review_mode(&CGlobalInfo::m_options.preview);
+ m_rx_check.erf_vif.open_file("exp/rtsp_short1_ipv6_rxcheck.erf");
+
+ m_rxcs.init();
+ m_mg.tw_drain();
+ m_rx_check.erf_vif.close_file();
+
+ CErfCmp cmp;
+ cmp.dump=1;
+ EXPECT_EQ(cmp.compare("exp/rtsp_short1_ipv6_rxcheck.erf","exp/rtsp_short1_ipv6_rxcheck-ex.erf"),true);
+ po->preview.set_ipv6_mode_enable(false);
+}
+
+TEST_F(rx_check_system, rx_system2_plugin_two_dir) {
+
+ m_rxcs.lpVf=&m_rx_check;
+ CParserOption * po =&CGlobalInfo::m_options;
+
+ po->m_rx_check_sampe=2; /* sample rate */
+ po->m_duration=100;
+ po->cfg_file ="cap2/rtsp_short1_slow.yaml";
+ m_rx_check.m_one_dir=false;
+
+ m_rxcs.init();
+ m_mg.tw_drain();
+
+ m_mg.Dump(stdout);
+
+ EXPECT_EQ(m_mg.m_stats.get_total_err(),0);
+}
+
+TEST_F(rx_check_system, rx_system2_plugin_two_dir_2) {
+
+ m_rxcs.lpVf=&m_rx_check;
+ CParserOption * po =&CGlobalInfo::m_options;
+
+ po->m_rx_check_sampe=2; /* sample rate */
+ po->m_duration=100;
+ po->cfg_file ="cap2/rtsp_short1.yaml";
+ m_rx_check.m_one_dir=false;
+
+ m_rxcs.init();
+ m_mg.tw_drain();
+
+ m_mg.Dump(stdout);
+
+ EXPECT_EQ(m_mg.m_stats.get_total_err(),0);
+}
+
+TEST_F(rx_check_system, rx_system_two_dir) {
+
+ m_rxcs.lpVf=&m_rx_check;
+ CParserOption * po =&CGlobalInfo::m_options;
+
+ po->m_rx_check_sampe=2; /* sample rate */
+ po->m_duration=100;
+ po->cfg_file ="cap2/dns.yaml";
+ m_rx_check.m_one_dir=false;
+
+ m_rxcs.init();
+ m_mg.tw_drain();
+
+ m_mg.Dump(stdout);
+
+ EXPECT_EQ(m_mg.m_stats.get_total_err(),0);
+}
+
+
+TEST_F(rx_check_system, rx_json) {
+
+ m_rxcs.lpVf=&m_rx_check;
+ CParserOption * po =&CGlobalInfo::m_options;
+
+ po->m_rx_check_sampe=2; /* sample rate */
+ po->m_duration=100;
+ po->cfg_file ="cap2/dns.yaml";
+
+ m_rxcs.init();
+ m_mg.tw_drain();
+
+ std::string json;
+ m_mg.dump_json(json);
+ printf(" %s \n",json.c_str());
+}
+
+
+
+//////////////////////////////////////////////////////////////
+
+
+class CNatCheck1 : public CRxCheckCallbackBase {
+public:
+
+ virtual void handle_packet(rte_mbuf_t * m){
+ char *mp=rte_pktmbuf_mtod(m, char*);
+ CNatOption * option=(CNatOption *)(mp+14+20);
+ IPHeader * ipv4=(IPHeader *)(mp+14);
+ if ( ipv4->getHeaderLength()>20 ) {
+ assert(ipv4->getTimeToLive()==255);
+ /* ip option packet */
+ printf(" rx got ip option packet ! \n");
+ mg->handle_packet_ipv4(option,ipv4);
+ delay(10); // delay for queue flush
+ mg->handle_aging(); // flush the RxRing
+ }
+ }
+ CNatRxManager * mg;
+};
+
+
+
+class nat_check_system : public testing::Test {
+ protected:
+ virtual void SetUp() {
+ gtest_init_once();
+
+ m_rx_check.m_callback=&m_callback;
+ m_callback.mg =&m_mg;
+ m_mg.Create();
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.setVMode(0);
+ po->preview.setFileWrite(true);
+ po->preview.set_lean_mode_enable(true);
+ }
+
+ virtual void TearDown() {
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.set_lean_mode_enable(false);
+ m_mg.Delete();
+ }
+public:
+ CRxCheckBasic m_rxcs;
+ CRxCheckIF m_rx_check;
+ CNatCheck1 m_callback;
+ CNatRxManager m_mg;
+
+};
+
+#if 0
+
+TEST_F(nat_check_system, nat_system1) {
+
+ m_rxcs.lpVf=&m_rx_check;
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->m_duration=2;
+ po->cfg_file ="cap2/dns.yaml";
+
+ m_rxcs.init();
+ m_mg.Dump(stdout);
+
+ //EXPECT_EQ(m_mg.m_stats.get_total_err(),0);
+}
+
+#endif
+
+//////////////////////////////////////////////////////////////
+
+class file_flow_info : public testing::Test {
+
+protected:
+ virtual void SetUp() {
+ gtest_init_once();
+ assert(m_flow_info.Create());
+ }
+
+ virtual void TearDown() {
+ m_flow_info.Delete();
+ }
+public:
+ CCapFileFlowInfo m_flow_info;
+
+};
+
+TEST_F(file_flow_info, f1) {
+ m_flow_info.load_cap_file("cap2/delay_10_rtp_250k_short.pcap",1,7) ;
+ m_flow_info.update_info();
+ //m_flow_info.Dump(stdout);
+
+ int i;
+ for (i=0; i<m_flow_info.Size(); i++) {
+ CFlowPktInfo * lp=m_flow_info.GetPacket((uint32_t)i);
+ uint16_t flow_id=lp->m_pkt_indication.m_desc.getFlowId();
+ switch (flow_id) {
+ case 0:
+ EXPECT_EQ(lp->m_pkt_indication.m_desc.GetMaxPktsPerFlow(),23);
+ EXPECT_EQ(lp->m_pkt_indication.m_desc.GetMaxFlowTimeout(),64);
+ EXPECT_EQ(lp->m_pkt_indication.m_desc.IsBiDirectionalFlow(),1);
+ break;
+ case 1:
+ EXPECT_EQ(lp->m_pkt_indication.m_desc.GetMaxPktsPerFlow(),7);
+ EXPECT_EQ(lp->m_pkt_indication.m_desc.GetMaxFlowTimeout(),10);
+ EXPECT_EQ(lp->m_pkt_indication.m_desc.IsBiDirectionalFlow(),0);
+
+ break;
+ case 2:
+ EXPECT_EQ(lp->m_pkt_indication.m_desc.GetMaxPktsPerFlow(),7);
+ EXPECT_EQ(lp->m_pkt_indication.m_desc.GetMaxFlowTimeout(),5);
+ EXPECT_EQ(lp->m_pkt_indication.m_desc.IsBiDirectionalFlow(),0);
+
+ break;
+ default:
+ assert(0);
+ }
+ }
+
+}
+
+TEST_F(file_flow_info, f2) {
+ m_flow_info.load_cap_file("cap2/citrix.pcap",1,0) ;
+ m_flow_info.update_info();
+
+
+ int i;
+ for (i=0; i<m_flow_info.Size(); i++) {
+ CFlowPktInfo * lp=m_flow_info.GetPacket((uint32_t)i);
+ uint16_t flow_id=lp->m_pkt_indication.m_desc.getFlowId();
+ switch (flow_id) {
+ case 0:
+ EXPECT_EQ(lp->m_pkt_indication.m_desc.GetMaxPktsPerFlow(),271);
+ EXPECT_EQ(lp->m_pkt_indication.m_desc.GetMaxFlowTimeout(),5);
+ break;
+ default:
+ assert(0);
+ }
+ }
+}
+
+TEST_F(file_flow_info, http_two_dir) {
+ m_flow_info.load_cap_file("avl/delay_10_http_browsing_0.pcap",1,0) ;
+ m_flow_info.update_info();
+ CFlowPktInfo * lp=m_flow_info.GetPacket((uint32_t)0);
+ EXPECT_EQ(lp->m_pkt_indication.m_desc.IsOneDirectionalFlow(),0);
+}
+
+TEST_F(file_flow_info, one_dir) {
+
+ m_flow_info.load_cap_file("avl/delay_rtp_160k_1_1_0.pcap",1,0) ;
+ m_flow_info.update_info();
+ CFlowPktInfo * lp=m_flow_info.GetPacket((uint32_t)0);
+ EXPECT_EQ(lp->m_pkt_indication.m_desc.IsOneDirectionalFlow(),1);
+}
+
+
+
+TEST_F(file_flow_info, nat_option_check) {
+ uint8_t buffer[8];
+ CNatOption *lp=(CNatOption *)&buffer[0];
+ lp->set_init_ipv4_header();
+ lp->set_fid(0x12345678);
+ lp->set_thread_id(7);
+ lp->dump(stdout);
+ EXPECT_EQ(lp->is_valid_ipv4_magic(),true);
+
+ lp->set_init_ipv6_header();
+ lp->dump(stdout);
+ EXPECT_EQ(lp->is_valid_ipv6_magic(),true);
+}
+
+TEST_F(file_flow_info, http_add_ipv4_option) {
+ m_flow_info.load_cap_file("avl/delay_10_http_browsing_0.pcap",1,0) ;
+ m_flow_info.update_info();
+ CFlowPktInfo * lp=m_flow_info.GetPacket((uint32_t)0);
+ printf(" before the change \n");
+ //lp->Dump(stdout);
+ //lp->m_packet->Dump(stdout,1);
+ CNatOption *lpNat =(CNatOption *)lp->push_ipv4_option_offline(8);
+ lpNat->set_init_ipv4_header();
+ lpNat->set_fid(0x12345678);
+ lpNat->set_thread_id(7);
+ lp->m_pkt_indication.l3.m_ipv4->updateCheckSum();
+ m_flow_info.save_to_erf("exp/http1_with_option.pcap",true);
+
+ m_flow_info.Delete();
+ CErfCmp cmp;
+ cmp.dump=1;
+ EXPECT_EQ(cmp.compare("exp/http1_with_option.pcap","exp/http1_with_option-ex.pcap"),true);
+}
+
+TEST_F(file_flow_info, http_add_ipv6_option) {
+ /* convert it to ipv6 */
+ CParserOption * po =&CGlobalInfo::m_options;
+ po->preview.set_ipv6_mode_enable(true);
+
+ m_flow_info.load_cap_file("avl/delay_10_http_browsing_0.pcap",1,0) ;
+ m_flow_info.update_info();
+ CFlowPktInfo * lp=m_flow_info.GetPacket((uint32_t)0);
+ //lp->Dump(stdout);
+ //lp->m_packet->Dump(stdout,1);
+ CNatOption *lpNat =(CNatOption *)lp->push_ipv6_option_offline(8);
+ lpNat->set_init_ipv6_header();
+ lpNat->set_fid(0x12345678);
+ lpNat->set_thread_id(7);
+ m_flow_info.save_to_erf("exp/http1_with_option_ipv6.pcap",true);
+ m_flow_info.Delete();
+ CErfCmp cmp;
+ cmp.dump=1;
+ EXPECT_EQ(cmp.compare("exp/http1_with_option_ipv6.pcap","exp/http1_with_option_ipv6-ex.pcap"),true);
+ po->preview.set_ipv6_mode_enable(false);
+}
+
+
+
+
+
+//////////////////////////////////////////////////////////////
+
+class time_histogram : public testing::Test {
+
+protected:
+ virtual void SetUp() {
+ m_hist.Create();
+ }
+
+ virtual void TearDown() {
+ m_hist.Delete();
+ }
+public:
+ CTimeHistogram m_hist;
+};
+
+TEST_F(time_histogram, test_average) {
+ int i;
+ int j;
+ for (j=0; j<10; j++) {
+ for (i=0; i<100; i++) {
+ m_hist.Add(10e-6);
+ }
+ for (i=0; i<100; i++) {
+ m_hist.Add(10e-3);
+ }
+ m_hist.update();
+ }
+
+ EXPECT_GT(m_hist.get_average_latency(),7400.0);
+ EXPECT_LT(m_hist.get_average_latency(),7600.0);
+
+ m_hist.Dump(stdout);
+}
+
+TEST_F(time_histogram, test_json) {
+ int i;
+ int j;
+ for (j=0; j<10; j++) {
+ for (i=0; i<100; i++) {
+ m_hist.Add(10e-6);
+ }
+ for (i=0; i<100; i++) {
+ m_hist.Add(10e-3);
+ }
+ m_hist.update();
+ }
+
+ m_hist.Dump(stdout);
+ std::string json ;
+ m_hist.dump_json("myHis",json );
+ printf(" %s \n",json.c_str());
+}
+
+
+
+class gt_jitter : public testing::Test {
+
+protected:
+ virtual void SetUp() {
+ }
+
+ virtual void TearDown() {
+ }
+public:
+ CJitter m_jitter;
+};
+
+
+class gt_jitter_uint : public testing::Test {
+
+protected:
+ virtual void SetUp() {
+ }
+
+ virtual void TearDown() {
+ }
+public:
+ CJitterUint m_jitter;
+};
+
+
+
+TEST_F(gt_jitter, jitter1) {
+ int i;
+ double a=0.000030;
+ for (i=0; i<100; i++) {
+ if (i%2) {
+ a+=0.000100;
+ }else{
+ a-=0.000100;
+ }
+ m_jitter.calc(a);
+ }
+ EXPECT_EQ((uint32_t)(m_jitter.get_jitter()*1000000.0), 99);
+}
+
+TEST_F(gt_jitter_uint, jitter2) {
+ int i;
+ int32_t a=30;
+ for (i=0; i<100; i++) {
+ if (i%2) {
+ a+=20;
+ }else{
+ a-=20;
+ }
+ m_jitter.calc(a);
+ }
+ EXPECT_EQ((uint32_t)(m_jitter.get_jitter()), 19);
+}
+
+
+class gt_ring : public testing::Test {
+
+protected:
+ virtual void SetUp() {
+ }
+
+ virtual void TearDown() {
+ }
+public:
+};
+
+TEST_F(gt_ring, ring1) {
+
+ CTRingSp<uint32_t> my;
+ bool res=my.Create("a",1024,0);
+ assert(res);
+
+ int i;
+ for (i=0; i<10; i++) {
+ uint32_t *p=new uint32_t();
+ *p=i;
+ assert(my.Enqueue(p)==0);
+ }
+ for (i=0; i<10; i++) {
+ uint32_t *p;
+ assert(my.Dequeue(p)==0);
+ EXPECT_EQ_UINT32(*p, i);
+ }
+ uint32_t *p;
+ assert(my.Dequeue(p)!=0);
+
+ EXPECT_EQ(my.isEmpty(), true);
+ EXPECT_EQ(my.isFull(), false);
+
+ my.Delete();
+}
+
+
+TEST_F(gt_ring, ring2) {
+ CMessagingManager ringmg;
+ ringmg.Create(8);
+
+ int i;
+ for (i=0; i<8; i++) {
+ CNodeRing * ln=ringmg.getRingDpToCp(i);
+ assert(ln);
+ CGenNode * node=new CGenNode();
+ node->m_flow_id=i;
+ assert(ln->Enqueue(node)==0);
+ }
+
+ for (i=0; i<8; i++) {
+ CNodeRing * ln=ringmg.getRingDpToCp(i);
+ assert(ln);
+ CGenNode * node;
+ assert(ln->Dequeue(node)==0);
+ EXPECT_EQ(node->m_flow_id, i);
+ delete node;
+ }
+
+ ringmg.Delete();
+}
+
+
+
+
+
+
+
+void my_free_map_uint32_t(uint32_t *p){
+ printf("before free %d \n",*p);
+ delete p;
+}
+
+
+TEST_F(gt_ring, ring3) {
+
+ typedef CGenericMap<uint32_t,uint32_t> my_test_map;
+ my_test_map my_map;
+
+ my_map.Create();
+ int i;
+
+ uint32_t *p;
+ for (i=0; i<10;i++) {
+ p=new uint32_t(i);
+ my_map.add((uint32_t)i,p);
+ }
+
+ for (i=0; i<10;i++) {
+ p=my_map.lookup((uint32_t)i);
+ printf(" %d \n",*p);
+ }
+
+ my_map.remove_all(my_free_map_uint32_t);
+ #if 0
+ for (i=0; i<10;i++) {
+ p=my_map.remove((uint32_t)i);
+ assert(p);
+ delete p;
+ }
+ #endif
+ my_map.Delete();
+}
+
+
+class gt_conf : public testing::Test {
+
+protected:
+ virtual void SetUp() {
+ }
+
+ virtual void TearDown() {
+ }
+public:
+};
+
+
+#if 0
+TEST_F(gt_conf, t1) {
+ CPlatformYamlInfo info;
+ info.load_from_yaml_file("cfg/ex1.yaml");
+ info.Dump(stdout);
+ CPlatformSocketInfoConfig cfg;
+ cfg.Create(&info.m_platform);
+
+ cfg.set_latency_thread_is_enabled(true);
+ cfg.set_number_of_dual_ports(1);
+ cfg.set_number_of_threads_per_ports(1);
+
+
+ cfg.sanity_check();
+ cfg.dump(stdout);
+}
+
+#endif
+
+