/* Hanoch 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 #include #include #include #include #include #include #include #include #include #include #define EXPECT_EQ_UINT32(a,b) EXPECT_EQ((uint32_t)(a),(uint32_t)(b)) /* basic stateless test */ class basic_stl : public testing::Test { protected: virtual void SetUp() { } virtual void TearDown() { } public: }; /** * Queue of RPC msgs for test * * @author hhaim */ class CBasicStl; struct CBasicStlDelayCommand { CBasicStlDelayCommand(){ m_node=NULL; } CGenNodeCommand * m_node; }; class CBasicStlMsgQueue { friend CBasicStl; public: CBasicStlMsgQueue(){ } /* user will allocate the message, no need to free it by this module */ void add_msg(TrexStatelessCpToDpMsgBase * msg){ m_msgs.push_back(msg); } void add_command(CBasicStlDelayCommand & command){ m_commands.push_back(command); } /* only if both port are idle we can exit */ void add_command(CFlowGenListPerThread * core, TrexStatelessCpToDpMsgBase * msg, double time){ CGenNodeCommand *node = (CGenNodeCommand *)core->create_node() ; node->m_type = CGenNode::COMMAND; node->m_cmd = msg; /* make sure it will be scheduled after the current node */ node->m_time = time ; CBasicStlDelayCommand command; command.m_node =node; add_command(command); } void clear(){ m_msgs.clear(); m_commands.clear(); } protected: std::vector m_msgs; std::vector m_commands; }; class CBasicStlSink { public: CBasicStlSink(){ m_core=0; } virtual void call_after_init(CBasicStl * m_obj)=0; virtual void call_after_run(CBasicStl * m_obj)=0; CFlowGenListPerThread * m_core; }; /** * handler for DP to CP messages * * @author imarom (19-Nov-15) */ class DpToCpHandler { public: virtual void handle(TrexStatelessDpToCpMsgBase *msg) = 0; }; class CBasicStl { public: CBasicStl(){ m_time_diff=0.001; m_threads=1; m_dump_json=false; m_dp_to_cp_handler = NULL; m_msg = NULL; m_sink = NULL; } void flush_dp_to_cp_messages() { CNodeRing *ring = CMsgIns::Ins()->getCpDp()->getRingDpToCp(0); while ( true ) { CGenNode * node = NULL; if (ring->Dequeue(node) != 0) { break; } assert(node); TrexStatelessDpToCpMsgBase * msg = (TrexStatelessDpToCpMsgBase *)node; if (m_dp_to_cp_handler) { m_dp_to_cp_handler->handle(msg); } delete msg; } } bool init(void){ CErfIFStl erf_vif; fl.Create(); fl.generate_p_thread_info(1); CFlowGenListPerThread * lpt; fl.m_threads_info[0]->set_vif(&erf_vif); CErfCmp cmp; cmp.dump=1; CMessagingManager * cp_dp = CMsgIns::Ins()->getCpDp(); m_ring_from_cp = cp_dp->getRingCpToDp(0); bool res=true; lpt=fl.m_threads_info[0]; if ( m_sink ){ m_sink->m_core =lpt; } char buf[100]; char buf_ex[100]; sprintf(buf,"%s-%d.erf",CGlobalInfo::m_options.out_file.c_str(),0); sprintf(buf_ex,"%s-%d-ex.erf",CGlobalInfo::m_options.out_file.c_str(),0); lpt->start_stateless_simulation_file(buf,CGlobalInfo::m_options.preview); /* add stream to the queue */ if ( m_msg ) { assert(m_ring_from_cp->Enqueue((CGenNode *)m_msg)==0); } if (m_msg_queue.m_msgs.size()>0) { for (auto msg : m_msg_queue.m_msgs) { assert(m_ring_from_cp->Enqueue((CGenNode *)msg)==0); } } if (m_sink) { m_sink->call_after_init(this); } /* add the commands */ if (m_msg_queue.m_commands.size()>0) { for (auto cmd : m_msg_queue.m_commands) { /* add commands nodes */
;;; plugin-all-apih-skel.el - vpp engine plug-in "all-apih.c" skeleton
;;;
;;; Copyright (c) 2016 Cisco and/or its affiliates.
;;; 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.

(require 'skeleton)

(define-skeleton skel-plugin-all-apih
"Insert a plug-in 'all_api_h.h' skeleton "
nil
'(if (not (boundp 'plugin-name))
     (setq plugin-name (read-string "Plugin name: ")))
'(setq PLUGIN-NAME (upcase plugin-name))
"
/*
 * " plugin-name "_all_api_h.h - skeleton vpp engine plug-in api #include file
 *
 * Copyright (c) <current-year> <your-organization>
 * 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 the generated file, see BUILT_SOURCES in Makefile.am */
#include <" plugin-name "/" plugin-name ".api.h>
")
std::vectorobjs; assert(compile.compile(port_id, streams, objs)); TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ ); TrexStatelessDpStop * lpStopCmd = new TrexStatelessDpStop(port_id); t1.m_msg_queue.add_msg(lpStartCmd); t1.m_msg_queue.add_msg(lpStopCmd); bool res=t1.init(); delete stream1 ; EXPECT_EQ_UINT32(1, res?1:0)<< "pass"; } TEST_F(basic_stl, simple_prog4) { CBasicStl t1; CParserOption * po =&CGlobalInfo::m_options; po->preview.setVMode(7); po->preview.setFileWrite(true); po->out_file ="exp/stl_simple_prog4"; TrexStreamsCompiler compile; std::vector streams; /* stream0 */ TrexStream * stream0 = new TrexStream(TrexStream::stCONTINUOUS, 0,300); stream0->set_pps(1.0); stream0->m_enabled = true; stream0->m_self_start = true; CPcapLoader pcap; pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000000); pcap.clone_packet_into_stream(stream0); streams.push_back(stream0); /* stream1 */ TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,100); stream1->set_pps(1.0); stream1->set_single_burst(5); stream1->m_enabled = true; stream1->m_self_start = true; stream1->m_next_stream_id=200; pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000001); pcap.clone_packet_into_stream(stream1); streams.push_back(stream1); /* stream1 */ TrexStream * stream2 = new TrexStream(TrexStream::stMULTI_BURST, 0,200); stream2->set_pps(1.0); stream2->m_isg_usec = 1000000; /*time betwean stream 1 to stream 2 */ stream2->m_enabled = true; stream2->m_self_start = false; stream2->set_multi_burst(5, 3, 2000000.0); // next stream is 100 - loop stream2->m_next_stream_id=100; pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000002); pcap.clone_packet_into_stream(stream2); streams.push_back(stream2); uint8_t port_id = 0; std::vectorobjs; assert(compile.compile(port_id, streams, objs)); TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 0, objs[0], 20.0 /*sec */ ); t1.m_msg = lpStartCmd; bool res=t1.init(); delete stream0 ; delete stream1 ; delete stream2 ; EXPECT_EQ_UINT32(1, res?1:0)<< "pass"; } TEST_F(basic_stl, simple_prog3) { CBasicStl t1; CParserOption * po =&CGlobalInfo::m_options; po->preview.setVMode(7); po->preview.setFileWrite(true); po->out_file ="exp/stl_simple_prog3"; TrexStreamsCompiler compile; std::vector streams; /* stream1 */ TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,100); stream1->set_pps(1.0); stream1->set_single_burst(5); stream1->m_enabled = true; stream1->m_self_start = true; stream1->m_next_stream_id=200; CPcapLoader pcap; pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000001); pcap.clone_packet_into_stream(stream1); streams.push_back(stream1); /* stream1 */ TrexStream * stream2 = new TrexStream(TrexStream::stMULTI_BURST, 0,200); stream2->set_pps(1.0); stream2->m_isg_usec = 1000000; /*time betwean stream 1 to stream 2 */ stream2->m_enabled = true; stream2->m_self_start = false; stream2->set_multi_burst(5, 3, 2000000.0); // next stream is 100 - loop stream2->m_next_stream_id=100; pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000002); pcap.clone_packet_into_stream(stream2); streams.push_back(stream2); uint8_t port_id = 0; std::vectorobjs; assert(compile.compile(port_id, streams, objs)); TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 50.0 /*sec */ ); t1.m_msg = lpstart; bool res=t1.init(); delete stream1 ; delete stream2 ; EXPECT_EQ_UINT32(1, res?1:0)<< "pass"; } TEST_F(basic_stl, simple_prog2) { CBasicStl t1; CParserOption * po =&CGlobalInfo::m_options; po->preview.setVMode(7); po->preview.setFileWrite(true); po->out_file ="exp/stl_simple_prog2"; TrexStreamsCompiler compile; std::vector streams; /* stream1 */ TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,100); stream1->set_pps(1.0); stream1->set_single_burst(5); stream1->m_enabled = true; stream1->m_self_start = true; stream1->m_next_stream_id=200; CPcapLoader pcap; pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000001); pcap.clone_packet_into_stream(stream1); streams.push_back(stream1); /* stream1 */ TrexStream * stream2 = new TrexStream(TrexStream::stSINGLE_BURST, 0,200); stream2->set_pps(1.0); stream2->set_single_burst(5); stream2->m_isg_usec = 2000000; /*time betwean stream 1 to stream 2 */ stream2->m_enabled = true; stream2->m_self_start = false; pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000002); pcap.clone_packet_into_stream(stream2); streams.push_back(stream2); uint8_t port_id = 0; std::vectorobjs; assert(compile.compile(port_id, streams, objs)); TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ ); t1.m_msg = lpstart; bool res=t1.init(); delete stream1 ; delete stream2 ; EXPECT_EQ_UINT32(1, res?1:0)<< "pass"; } TEST_F(basic_stl, simple_prog1) { CBasicStl t1; CParserOption * po =&CGlobalInfo::m_options; po->preview.setVMode(7); po->preview.setFileWrite(true); po->out_file ="exp/stl_simple_prog1"; TrexStreamsCompiler compile; std::vector streams; /* stream1 */ TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,100); stream1->set_pps(1.0); stream1->set_single_burst(5); stream1->m_enabled = true; stream1->m_self_start = true; stream1->m_next_stream_id=200; CPcapLoader pcap; pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000001); pcap.clone_packet_into_stream(stream1); streams.push_back(stream1); /* stream1 */ TrexStream * stream2 = new TrexStream(TrexStream::stSINGLE_BURST, 0,200); stream2->set_pps(1.0); stream2->set_single_burst(5); stream2->m_enabled = true; stream2->m_self_start = false; pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000002); pcap.clone_packet_into_stream(stream2); streams.push_back(stream2); uint8_t port_id = 0; std::vectorobjs; assert(compile.compile(port_id, streams, objs)); TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ ); t1.m_msg = lpstart; bool res=t1.init(); delete stream1 ; delete stream2 ; EXPECT_EQ_UINT32(1, res?1:0)<< "pass"; } TEST_F(basic_stl, single_pkt_burst1) { CBasicStl t1; CParserOption * po =&CGlobalInfo::m_options; po->preview.setVMode(7); po->preview.setFileWrite(true); po->out_file ="exp/stl_single_pkt_burst1"; TrexStreamsCompiler compile; std::vector streams; TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST, 0,0); stream1->set_pps(1.0); stream1->set_single_burst(5); stream1->m_enabled = true; stream1->m_self_start = true; CPcapLoader pcap; pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000001); pcap.clone_packet_into_stream(stream1); streams.push_back(stream1); uint8_t port_id = 0; std::vectorobjs; assert(compile.compile(port_id, streams, objs)); TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ ); t1.m_msg = lpstart; bool res=t1.init(); delete stream1 ; EXPECT_EQ_UINT32(1, res?1:0)<< "pass"; } TEST_F(basic_stl, single_pkt) { CBasicStl t1; CParserOption * po =&CGlobalInfo::m_options; po->preview.setVMode(7); po->preview.setFileWrite(true); po->out_file ="exp/stl_single_stream"; TrexStreamsCompiler compile; uint8_t port_id=0; std::vector streams; TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0); stream1->set_pps(1.0); stream1->m_enabled = true; stream1->m_self_start = true; stream1->m_port_id= port_id; CPcapLoader pcap; pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000001); pcap.clone_packet_into_stream(stream1); streams.push_back(stream1); // stream - clean std::vectorobjs; assert(compile.compile(port_id, streams, objs)); TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ ); t1.m_msg = lpstart; bool res=t1.init(); delete stream1 ; EXPECT_EQ_UINT32(1, res?1:0)<< "pass"; } TEST_F(basic_stl, multi_pkt1) { CBasicStl t1; CParserOption * po =&CGlobalInfo::m_options; po->preview.setVMode(7); po->preview.setFileWrite(true); po->out_file ="exp/stl_multi_pkt1"; TrexStreamsCompiler compile; std::vector streams; TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0); stream1->set_pps(1.0); stream1->m_enabled = true; stream1->m_self_start = true; CPcapLoader pcap; pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000001); pcap.clone_packet_into_stream(stream1); streams.push_back(stream1); TrexStream * stream2 = new TrexStream(TrexStream::stCONTINUOUS,0,1); stream2->set_pps(2.0); stream2->m_enabled = true; stream2->m_self_start = true; stream2->m_isg_usec = 1000.0; /* 1 msec */ pcap.update_ip_src(0x20000001); pcap.clone_packet_into_stream(stream2); streams.push_back(stream2); // stream - clean uint8_t port_id = 0; std::vectorobjs; assert(compile.compile(port_id, streams, objs)); TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ ); t1.m_msg = lpstart; bool res=t1.init(); delete stream1 ; delete stream2 ; EXPECT_EQ_UINT32(1, res?1:0)<< "pass"; } /* check disabled stream with multiplier of 5*/ TEST_F(basic_stl, multi_pkt2) { CBasicStl t1; CParserOption * po =&CGlobalInfo::m_options; po->preview.setVMode(7); po->preview.setFileWrite(true); po->out_file ="exp/stl_multi_pkt2"; TrexStreamsCompiler compile; std::vector streams; TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,0); stream1->set_pps(1.0); stream1->m_enabled = true; stream1->m_self_start = true; CPcapLoader pcap; pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000001); pcap.clone_packet_into_stream(stream1); streams.push_back(stream1); TrexStream * stream2 = new TrexStream(TrexStream::stCONTINUOUS,0,1); stream2->set_pps(2.0); stream2->m_enabled = false; stream2->m_self_start = false; stream2->m_isg_usec = 1000.0; /* 1 msec */ pcap.update_ip_src(0x20000001); pcap.clone_packet_into_stream(stream2); streams.push_back(stream2); // stream - clean uint8_t port_id = 0; std::vectorobjs; assert(compile.compile(port_id, streams, objs, 1, 5.0)); TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 10.0 /*sec */ ); t1.m_msg = lpstart; bool res=t1.init(); delete stream1 ; delete stream2 ; EXPECT_EQ_UINT32(1, res?1:0)<< "pass"; } TEST_F(basic_stl, multi_burst1) { CBasicStl t1; CParserOption * po =&CGlobalInfo::m_options; po->preview.setVMode(7); po->preview.setFileWrite(true); po->out_file ="exp/stl_multi_burst1"; TrexStreamsCompiler compile; std::vector streams; TrexStream * stream1 = new TrexStream(TrexStream::stMULTI_BURST,0,0); stream1->set_pps(1.0); stream1->set_multi_burst(5, 3, 2000000.0); stream1->m_enabled = true; stream1->m_self_start = true; CPcapLoader pcap; pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000001); pcap.clone_packet_into_stream(stream1); streams.push_back(stream1); uint8_t port_id = 0; std::vectorobjs; assert(compile.compile(port_id, streams, objs)); TrexStatelessDpStart *lpstart = new TrexStatelessDpStart(port_id, 0, objs[0], 40.0 /*sec */ ); t1.m_msg = lpstart; bool res=t1.init(); delete stream1 ; EXPECT_EQ_UINT32(1, res?1:0)<< "pass"; } /********************************************* Itay Tests Start *************************************/ /** * check that continous stream does not point to another stream * (makes no sense) */ TEST_F(basic_stl, compile_bad_1) { TrexStreamsCompiler compile; std::vector streams; TrexStream * stream1 = new TrexStream(TrexStream::stCONTINUOUS,0,2); stream1->m_enabled = true; stream1->set_pps(52.0); stream1->m_next_stream_id = 3; streams.push_back(stream1); std::string err_msg; std::vectorobjs; EXPECT_FALSE(compile.compile(0, streams, objs, 1, 1, &err_msg)); delete stream1; } /** * check for streams pointing to non exsistant streams * * @author imarom (16-Nov-15) */ TEST_F(basic_stl, compile_bad_2) { TrexStreamsCompiler compile; std::vector streams; TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST,0,1); stream1->m_enabled = true; stream1->set_pps(1.0); stream1->set_single_burst(200); /* non existant next stream */ stream1->m_next_stream_id = 5; TrexStream * stream2 = new TrexStream(TrexStream::stCONTINUOUS,0,2); stream1->set_pps(52.0); streams.push_back(stream1); streams.push_back(stream2); uint8_t port_id = 0; std::string err_msg; std::vectorobjs; EXPECT_FALSE(compile.compile(port_id, streams, objs, 1, 1, &err_msg)); delete stream1; delete stream2; } /** * check for "dead streams" in the mesh * a streams that cannot be reached * * @author imarom (16-Nov-15) */ TEST_F(basic_stl, compile_bad_3) { TrexStreamsCompiler compile; std::vector streams; TrexStream *stream; /* stream 1 */ stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 231); stream->m_enabled = true; stream->set_pps(1.0); stream->set_single_burst(200); stream->m_next_stream_id = 5481; stream->m_self_start = true; streams.push_back(stream); /* stream 2 */ stream = new TrexStream(TrexStream::stCONTINUOUS, 0, 5481); stream->m_enabled = true; stream->m_next_stream_id = -1; stream->m_self_start = false; stream->set_pps(52.0); streams.push_back(stream); /* stream 3 */ stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 1928); stream->m_enabled = true; stream->set_pps(1.0); stream->set_single_burst(200); stream->m_next_stream_id = -1; stream->m_self_start = true; streams.push_back(stream); /* stream 4 */ stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 41231); stream->m_enabled = true; stream->set_pps(1.0); stream->set_single_burst(200); stream->m_next_stream_id = 3928; stream->m_self_start = false; streams.push_back(stream); /* stream 5 */ stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 3928); stream->m_enabled = true; stream->set_pps(1.0); stream->set_single_burst(200); stream->m_next_stream_id = 41231; stream->m_self_start = false; streams.push_back(stream); /* compile */ std::string err_msg; std::vectorobjs; EXPECT_FALSE(compile.compile(0, streams, objs, 1, 1, &err_msg)); for (auto stream : streams) { delete stream; } } TEST_F(basic_stl, compile_with_warnings) { TrexStreamsCompiler compile; std::vector streams; TrexStream *stream; /* stream 1 */ stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 231); stream->m_enabled = true; stream->set_pps(1.0); stream->set_single_burst(200); stream->m_next_stream_id = 1928; stream->m_self_start = true; streams.push_back(stream); /* stream 2 */ stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 5481); stream->m_enabled = true; stream->m_next_stream_id = 1928; stream->m_self_start = true; stream->set_pps(52.0); streams.push_back(stream); /* stream 3 */ stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 1928); stream->m_enabled = true; stream->set_pps(1.0); stream->set_single_burst(200); stream->m_next_stream_id = -1; stream->m_self_start = true; streams.push_back(stream); /* compile */ std::string err_msg; std::vectorobjs; EXPECT_TRUE(compile.compile(0, streams, objs, 1, 1, &err_msg)); delete objs[0]; EXPECT_TRUE(compile.get_last_compile_warnings().size() == 1); for (auto stream : streams) { delete stream; } } TEST_F(basic_stl, compile_good_stream_id_compres) { TrexStreamsCompiler compile; std::vector streams; TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST,0,700); stream1->m_self_start = true; stream1->m_enabled = true; stream1->set_pps(1.0); stream1->set_single_burst(200); /* non existant next stream */ stream1->m_next_stream_id = 800; TrexStream * stream2 = new TrexStream(TrexStream::stSINGLE_BURST,0,800); stream2->set_pps(52.0); stream2->m_enabled = true; stream2->m_next_stream_id = 700; stream2->set_single_burst(300); streams.push_back(stream1); streams.push_back(stream2); uint8_t port_id = 0; std::string err_msg; std::vectorobjs; EXPECT_TRUE(compile.compile(port_id, streams, objs, 1, 1, &err_msg)); printf(" %s \n",err_msg.c_str()); objs[0]->Dump(stdout); EXPECT_EQ_UINT32(objs[0]->get_objects()[0].m_stream->m_stream_id,0); EXPECT_EQ_UINT32(objs[0]->get_objects()[0].m_stream->m_next_stream_id,1); EXPECT_EQ_UINT32(objs[0]->get_objects()[1].m_stream->m_stream_id,1); EXPECT_EQ_UINT32(objs[0]->get_objects()[1].m_stream->m_next_stream_id,0); delete objs[0]; delete stream1; delete stream2; } class DpToCpHandlerStopEvent: public DpToCpHandler { public: DpToCpHandlerStopEvent(int event_id) { m_event_id = event_id; } virtual void handle(TrexStatelessDpToCpMsgBase *msg) { /* first the message must be an event */ TrexDpPortEventMsg *event = dynamic_cast(msg); EXPECT_TRUE(event != NULL); EXPECT_TRUE(event->get_event_type() == TrexDpPortEvent::EVENT_STOP); EXPECT_TRUE(event->get_event_id() == m_event_id); EXPECT_TRUE(event->get_port_id() == 0); } private: int m_event_id; }; TEST_F(basic_stl, dp_stop_event) { CBasicStl t1; CParserOption * po =&CGlobalInfo::m_options; po->preview.setVMode(7); po->preview.setFileWrite(true); po->out_file ="exp/ignore"; TrexStreamsCompiler compile; uint8_t port_id=0; std::vector streams; TrexStream * stream1 = new TrexStream(TrexStream::stSINGLE_BURST,0,0); stream1->set_pps(1.0); stream1->set_single_burst(100); stream1->m_enabled = true; stream1->m_self_start = true; stream1->m_port_id= port_id; CPcapLoader pcap; pcap.load_pcap_file("cap2/udp_64B.pcap",0); pcap.update_ip_src(0x10000001); pcap.clone_packet_into_stream(stream1); streams.push_back(stream1); // stream - clean std::vectorobjs; assert(compile.compile(port_id, streams, objs)); TrexStatelessDpStart *lpStartCmd = new TrexStatelessDpStart(port_id, 17, objs[0], 10.0 /*sec */ ); t1.m_msg = lpStartCmd; /* let me handle these */ DpToCpHandlerStopEvent handler(17); t1.m_dp_to_cp_handler = &handler; bool res=t1.init(); EXPECT_EQ_UINT32(1, res?1:0); delete stream1 ; } TEST_F(basic_stl, graph_generator1) { std::vector streams; TrexStreamsGraph graph; TrexStream *stream; /* stream 1 */ stream = new TrexStream(TrexStream::stSINGLE_BURST, 0, 1); stream->m_enabled = true; stream->m_self_start = true; stream->m_isg_usec = 42; stream->set_pps(10); stream->set_single_burst(43281); stream->m_pkt.len = 512; stream->m_next_stream_id = 2; streams.push_back(stream); /* stream 2 */ stream = new TrexStream(TrexStream::stMULTI_BURST, 0, 2); stream->m_enabled = true; stream->m_self_start = false; stream->set_pps(20); stream->set_multi_burst(4918, 13, 7); stream->m_next_stream_id = -1; stream->m_pkt.len = 64; streams.push_back(stream); /* stream 3 */ stream = new TrexStream(TrexStream::stCONTINUOUS, 0, 3); stream->m_enabled = true; stream->m_self_start = true; stream->m_isg_usec = 50; stream->set_pps(30); stream->m_next_stream_id = -1; stream->m_pkt.len = 1512; streams.push_back(stream); const TrexStreamsGraphObj *obj = graph.generate(streams); EXPECT_EQ(obj->get_max_bps(), 405120); EXPECT_EQ(obj->get_max_pps(), 50); for (auto stream : streams) { delete stream; } delete obj; } TEST_F(basic_stl, graph_generator2) { std::vector streams; TrexStreamsGraph graph; TrexStream *stream; /* add some multi burst streams */ stream = new TrexStream(TrexStream::stMULTI_BURST, 0, 1); stream->m_enabled = true; stream->m_self_start = true; stream->set_pps(1000); /* a burst of 2000 packets with a delay of 1 second */ stream->m_isg_usec = 0; stream->set_multi_burst(1000, 500, 1000 * 1000); stream->m_pkt.len = 64; stream->m_next_stream_id = -1; streams.push_back(stream); /* another multi burst stream but with a shorter burst ( less 2 ms ) and higher ibg (2 ms) , one milli for each side */ stream = new TrexStream(TrexStream::stMULTI_BURST, 0, 2); stream->m_enabled = true; stream->m_self_start = true; stream->set_pps(1000); stream->m_isg_usec = 1000 * 1000 + 1000; stream->set_multi_burst(1000 - 2, 1000, 1000 * 1000 + 2000); stream->m_pkt.len = 128; stream->m_next_stream_id = -1; streams.push_back(stream); const TrexStreamsGraphObj *obj = graph.generate(streams); EXPECT_EQ(obj->get_max_pps(), 1000.0); EXPECT_EQ(obj->get_max_bps(), (1000 * (128 + 4) * 8)); for (auto stream : streams) { delete stream; } delete obj; } /* stress test */ #if 0 TEST_F(basic_stl, graph_generator2) { std::vector streams; TrexStreamsGraph graph; TrexStream *stream; /* add some multi burst streams */ stream = new TrexStream(TrexStream::stMULTI_BURST, 0, 1); stream->m_enabled = true; stream->m_self_start = true; stream->m_isg_usec = 100; stream->set_pps(20); stream->set_multi_burst(4918, 321312, 15); stream->m_next_stream_id = -1; stream->m_pkt.len = 64; streams.push_back(stream); stream = new TrexStream(TrexStream::stMULTI_BURST, 0, 2); stream->m_enabled = true; stream->m_self_start = true; stream->m_isg_usec = 59281; stream->set_pps(30); stream->set_multi_burst(4918, 51040, 27); stream->m_next_stream_id = -1; stream->m_pkt.len = 64; streams.push_back(stream); stream = new TrexStream(TrexStream::stMULTI_BURST, 0, 3); stream->m_enabled = true; stream->m_self_start = true; stream->m_isg_usec = 59281492; stream->set_pps(40); stream->set_multi_burst(4918, 412312, 2917); stream->m_next_stream_id = -1; stream->m_pkt.len = 64; streams.push_back(stream); /* stream 3 */ stream = new TrexStream(TrexStream::stCONTINUOUS, 0, 4); stream->m_enabled = true; stream->m_self_start = true; stream->m_isg_usec = 50; stream->set_pps(30); stream->m_next_stream_id = -1; stream->m_pkt.len = 1512; streams.push_back(stream); const TrexStreamsGraphObj &obj = graph.generate(streams); printf("event_count is: %lu, max BPS: %f, max PPS: %f\n", obj.get_events().size(), obj.get_max_bps(), obj.get_max_pps()); // for (const TrexStreamsGraphObj::rate_event_st &ev : obj.get_events()) { // printf("time: %f, diff bps: %f, diff pps: %f\n", ev.time, ev.diff_bps, ev.diff_pps); // } for (auto stream : streams) { delete stream; } } #endif /********************************************* Itay Tests End *************************************/