From b3c544bd3d3e150660774d4588419e75058bdf97 Mon Sep 17 00:00:00 2001 From: Ido Barnea Date: Tue, 10 Jan 2017 16:01:27 +0200 Subject: Add client config unit test + fixes to unit tests infra Signed-off-by: Ido Barnea --- .gitignore | 1 + scripts/cap2/cluster_example.yaml | 65 ++++++++++++++++++ scripts/cfg/client_cfg_template.yaml | 56 --------------- scripts/exp/client_cfg_dns-0-ex.erf | Bin 0 -> 2016 bytes src/bp_gtest.cpp | 119 +------------------------------- src/bp_gtest.h | 128 +++++++++++++++++++++++++++++++++++ src/bp_sim.h | 79 +++++++++++---------- src/gtest/client_cfg_test.cpp | 51 +++++++++++--- 8 files changed, 279 insertions(+), 220 deletions(-) create mode 100644 scripts/cap2/cluster_example.yaml delete mode 100644 scripts/cfg/client_cfg_template.yaml create mode 100644 scripts/exp/client_cfg_dns-0-ex.erf create mode 100644 src/bp_gtest.h diff --git a/.gitignore b/.gitignore index a8fb3f8b..097e76a4 100644 --- a/.gitignore +++ b/.gitignore @@ -27,6 +27,7 @@ scripts/automation/trex_control_plane/doc/_build/* scripts/automation/trex_control_plane/doc_stl/_build/* scripts/a.pcap +scripts/exp/client_cfg_dns-0.erf scripts/exp/pcap_remote_dual-0.erf scripts/exp/stl_vm_split_client_var.erf-0.erf scripts/exp/stl_vm_split_flow_var_big_range.erf-0.erf diff --git a/scripts/cap2/cluster_example.yaml b/scripts/cap2/cluster_example.yaml new file mode 100644 index 00000000..6168d131 --- /dev/null +++ b/scripts/cap2/cluster_example.yaml @@ -0,0 +1,65 @@ +# +# Cluster configuration example file +# The file must contain the following fields +# +# 'vlan' - Set to true, if the entire configuration is under VLAN. False otherwise. +# if set to true, each client group must include vlan configuration +# +# 'groups' - Each client group must contain range of IPs +# and initiator and responder maps +# 'count' is the number of devices on the group. +# +# initiator and responder can contain 'vlan', 'src_mac', 'dst_mac', 'next_hop'. +# + +vlan: true + +groups: + +- ip_start : 16.0.0.1 + ip_end : 16.0.0.4 + initiator : + vlan : 100 + dst_mac : "00:00:00:01:00:00" + responder : + vlan : 200 + dst_mac : "00:00:00:01:00:00" + + count : 2 + +- ip_start : 16.0.0.5 + ip_end : 16.0.0.12 + initiator : + vlan : 101 + dst_mac : "01:00:00:00:01:01" + + responder : + vlan : 201 + dst_mac : "01:00:00:00:02:01" + + count : 4 + +- ip_start : 16.0.0.13 + ip_end : 16.0.0.30 + + initiator : + vlan : 103 + dst_mac : "02:00:00:00:01:01" + responder : + + vlan : 203 + dst_mac : "02:00:00:00:02:01" + + count : 8 + +- ip_start : 16.0.0.31 + ip_end : 16.0.1.255 + + initiator : + vlan : 104 + dst_mac : "04:00:00:00:01:01" + responder : + + vlan : 204 + dst_mac : "04:00:00:00:02:01" + diff --git a/scripts/cfg/client_cfg_template.yaml b/scripts/cfg/client_cfg_template.yaml deleted file mode 100644 index 8257b981..00000000 --- a/scripts/cfg/client_cfg_template.yaml +++ /dev/null @@ -1,56 +0,0 @@ -# -# Client configuration example file -# The file must contain the following fields -# -# 'vlan' - is the entire configuration under VLAN -# if so, each client group must include vlan -# configuration -# -# 'groups' - each client group must contain a range of IP -# and initiator and responder maps -# 'count' represents the number of MAC devices -# on the group. -# -# initiator and responder can contain 'vlan', 'src_mac', 'dst_mac' -# - -vlan: true - -groups: - -- ip_start : 5.0.0.1 - ip_end : 5.0.0.4 - initiator : - vlan : 100 - dst_mac : "00:00:00:01:00:00" - responder : - vlan : 200 - dst_mac : "00:00:00:01:00:00" - - count : 2 - -- ip_start : 5.0.0.5 - ip_end : 5.0.0.12 - initiator : - vlan : 101 - dst_mac : "01:00:00:00:01:01" - - responder: - vlan : 201 - dst_mac : "01:00:00:00:02:01" - - count : 4 - -- ip_start : 5.0.0.13 - ip_end : 5.0.0.30 - - initiator : - vlan : 103 - dst_mac : "02:00:00:00:01:01" - responder : - - vlan : 203 - dst_mac : "02:00:00:00:02:01" - - count : 8 - diff --git a/scripts/exp/client_cfg_dns-0-ex.erf b/scripts/exp/client_cfg_dns-0-ex.erf new file mode 100644 index 00000000..cb7ff995 Binary files /dev/null and b/scripts/exp/client_cfg_dns-0-ex.erf differ diff --git a/src/bp_gtest.cpp b/src/bp_gtest.cpp index 4c04dde9..be601957 100755 --- a/src/bp_gtest.cpp +++ b/src/bp_gtest.cpp @@ -34,6 +34,7 @@ limitations under the License. #include "stateful_rx_core.h" #include "nat_check_flow_table.h" #include "utl_ipg_bucket.h" +#include "bp_gtest.h" int test_policer(){ CPolicer policer; @@ -113,124 +114,6 @@ int test_human_p(){ return (0); } - - - - - -#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 = NULL; - 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; im_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 ; iGenerateOneSourcePort(); - } - } - CGlobalInfo::m_options.m_run_mode = CParserOption::RUN_MODE_BATCH; - lpt->start_generate_stateful(buf,CGlobalInfo::m_options.preview); - lpt->m_node_gen.DumpHist(stdout); - - cmp.d_sec = m_time_diff; - //compare - 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(0, tuple.getClientId(),tuple.getClientPort()); - - for (i=0 ; im_smart_gen.FreePort(0,tuple.getClientId(),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() { diff --git a/src/bp_gtest.h b/src/bp_gtest.h new file mode 100644 index 00000000..0bc66eac --- /dev/null +++ b/src/bp_gtest.h @@ -0,0 +1,128 @@ +/* +Copyright (c) 2017-2017 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. +*/ + +#ifndef _BP_GTEST_H_ +#define _BP_GTEST_H_ + +#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 = NULL; + CTupleBase tuple; + CErfIF erf_vif; + + fl.Create(); + m_saved_packet_padd_offset=0; + fl.load_from_yaml(CGlobalInfo::m_options.cfg_file,m_threads); + + if (CGlobalInfo::m_options.client_cfg_file != "") { + try { + fl.load_client_config_file(CGlobalInfo::m_options.client_cfg_file); + // The simulator only test MAC address configs, so this parameter is not used + CManyIPInfo pretest_result; + fl.set_client_config_resolved_macs(pretest_result); + } catch (const std::runtime_error &e) { + std::cout << "\n*** " << e.what() << "\n\n"; + exit(-1); + } + CGlobalInfo::m_options.preview.set_client_cfg_enable(true); + } + + fl.generate_p_thread_info(m_threads); + fl.m_threads_info[0]->set_vif(&erf_vif); + CErfCmp cmp; + cmp.dump = 1; + bool res = true; + int i; + CFlowGenListPerThread * lpt; + + for (i=0; im_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 ; iGenerateOneSourcePort(); + } + } + CGlobalInfo::m_options.m_run_mode = CParserOption::RUN_MODE_BATCH; + lpt->start_generate_stateful(buf,CGlobalInfo::m_options.preview); + lpt->m_node_gen.DumpHist(stdout); + cmp.d_sec = m_time_diff; + //compare generated file to expected file + 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(0, tuple.getClientId(),tuple.getClientPort()); + for (i=0 ; i < m_req_ports; i++) { + fl.m_threads_info[0]->m_smart_gen.FreePort(0,tuple.getClientId(),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; +}; + +#endif diff --git a/src/bp_sim.h b/src/bp_sim.h index 4df1dcd9..282e7fe4 100755 --- a/src/bp_sim.h +++ b/src/bp_sim.h @@ -649,9 +649,12 @@ typedef struct mac_align_t_ { struct CMacAddrCfg { public: - CMacAddrCfg (){ - memset(u.m_data,0,sizeof(u.m_data)); - u.m_mac.dest[3]=1; + CMacAddrCfg () { + reset(); + } + void reset () { + memset(u.m_data, 0, sizeof(u.m_data)); + u.m_mac.dest[3] = 1; u.m_mac.is_set = 0; } union { @@ -708,36 +711,49 @@ public: }; public: - CParserOption(){ - m_factor=1.0; - m_mbuf_factor=1.0; - m_duration=0.0; - m_latency_rate =0; - m_latency_mask =0xffffffff; - m_latency_prev=0; - m_wait_before_traffic=1; - m_zmq_port=4500; - m_telnet_port =4501; - m_platform_factor=1.0; - m_expected_portd = 4; /* should be at least the number of ports found in the system but could be less */ - m_vlan_port[0]=100; - m_vlan_port[1]=100; - m_rx_check_sample=0; + + void reset() { + preview.clean(); + m_tw_buckets = 1024; + m_tw_levels = 3; + m_active_flows = 0; + m_factor = 1.0; + m_mbuf_factor = 1.0; + m_duration = 0.0; + m_platform_factor = 1.0; + m_vlan_port[0] = 100; + m_vlan_port[1] = 100; + memset(m_src_ipv6, 0, sizeof(m_src_ipv6)); + memset(m_dst_ipv6, 0, sizeof(m_dst_ipv6)); + memset(m_ip_cfg, 0, sizeof(m_ip_cfg)); + m_latency_rate = 0; + m_latency_mask = 0xffffffff; + m_latency_prev = 0; + m_rx_check_sample = 0; m_rx_check_hops = 0; - m_io_mode=1; - m_run_flags=0; - prefix=""; - m_run_mode = RUN_MODE_INVALID; + m_wait_before_traffic = 1; + m_zmq_port = 4500; + m_telnet_port = 4501; + m_expected_portd = 4; /* should be at least the number of ports found in the system but could be less */ + m_io_mode = 1; + m_run_flags = 0; m_l_pkt_mode = 0; - m_rx_thread_enabled = false; + m_learn_mode = 0; + m_debug_pkt_proto = 0; m_arp_ref_per = 120; // in seconds - m_tw_buckets = 1024; - m_tw_levels = 3; + m_rx_thread_enabled = false; + m_run_mode = RUN_MODE_INVALID; + cfg_file = ""; + client_cfg_file = ""; + platform_cfg_file = ""; + out_file = ""; + prefix = ""; set_tw_bucket_time_in_usec(20.0); - m_active_flows=0; - } + CParserOption(){ + reset(); + } CPreviewMode preview; uint16_t m_tw_buckets; @@ -768,23 +784,17 @@ public: uint16_t m_arp_ref_per; bool m_rx_thread_enabled; trex_run_mode_e m_run_mode; - - - std::string cfg_file; std::string client_cfg_file; std::string platform_cfg_file; - std::string out_file; std::string prefix; std::vector dump_interfaces; - - CMacAddrCfg m_mac_addr[TREX_MAX_PORTS]; double m_tw_bucket_time_sec; double m_tw_bucket_time_sec_level1; - +public: uint8_t * get_src_mac_addr(int if_index){ return (m_mac_addr[if_index].u.m_mac.src); } @@ -792,7 +802,6 @@ public: return (m_mac_addr[if_index].u.m_mac.dest); } -public: uint32_t get_expected_ports(){ return (m_expected_portd); } diff --git a/src/gtest/client_cfg_test.cpp b/src/gtest/client_cfg_test.cpp index 4e93f3c5..987fc252 100644 --- a/src/gtest/client_cfg_test.cpp +++ b/src/gtest/client_cfg_test.cpp @@ -1,6 +1,6 @@ /* Ido Barnea - + Cisco Systems, Inc. */ @@ -23,6 +23,16 @@ limitations under the License. #include "../bp_sim.h" #include #include +#include "bp_gtest.h" + +class client_cfg : public testing::Test { + protected: + virtual void SetUp() { + } + virtual void TearDown() { + } + public: +}; class basic_client_cfg : public testing::Test { protected: @@ -33,6 +43,7 @@ class basic_client_cfg : public testing::Test { public: }; +// testing IP resolution relevant classes TEST_F(basic_client_cfg, test1) { uint32_t ip_start = 0x10010101; uint32_t ip_end = 0x100101ff; @@ -58,8 +69,8 @@ TEST_F(basic_client_cfg, test1) { tg_yam_info.m_client_pool.push_back(s_pool); CGlobalInfo::m_options.m_expected_portd = 4; - printf("Expected ports %d\n", CGlobalInfo::m_options.m_expected_portd); - + printf("Expected ports %d\n", CGlobalInfo::m_options.m_expected_portd); + std::string tmp_file_name = "client_cfg_gtest_GENERATED.yaml"; FILE *fd = fopen(tmp_file_name.c_str(), "w"); @@ -72,7 +83,7 @@ TEST_F(basic_client_cfg, test1) { cfg_ext.m_responder.set_next_hop(next_hop_resp); cfg_ext.m_initiator.set_vlan(vlan_init); cfg_ext.m_responder.set_vlan(vlan_resp); - + cfg_ent.set_params(ip_start, ip_end, test_count); cfg_ent.set_cfg(cfg_ext); @@ -95,7 +106,7 @@ TEST_F(basic_client_cfg, test1) { test_db.load_yaml_file(tmp_file_name); test_db.set_tuple_gen_info(&tg_yam_info); test_db.get_entry_list(ent_list); - + // We expect ports for first two groups to be found. // This group addresses should not appear in the list, since @@ -114,13 +125,13 @@ TEST_F(basic_client_cfg, test1) { case 2: assert(port == i); assert(vlan == vlan_init); - assert(dst_ip == next_hop_init); + assert(dst_ip == next_hop_init); break; case 1: case 3: assert(port == i); assert(vlan == vlan_resp); - assert(dst_ip == next_hop_resp); + assert(dst_ip == next_hop_resp); break; default: fprintf(stderr, "Test failed. Too many entries returned\n"); @@ -141,12 +152,12 @@ TEST_F(basic_client_cfg, test1) { COneIPv4Info ip0_2(next_hop_init + 1, vlan_init, mac1, 0); COneIPv4Info ip1_1(next_hop_resp, vlan_resp, mac2, 1); COneIPv4Info ip1_2(next_hop_resp + 1, vlan_resp, mac3, 1); - + many_ip.insert(ip0_1); many_ip.insert(ip0_2); many_ip.insert(ip1_1); many_ip.insert(ip1_2); - + test_db.set_resolved_macs(many_ip); ClientCfgBase cfg0; @@ -167,7 +178,7 @@ TEST_F(basic_client_cfg, test1) { ent0->assign(cfg0); assert (!memcmp(cfg0.m_responder.get_dst_mac_addr() , mac3.GetConstBuffer(), ETHER_ADDR_LEN)); - + assert(ent1 != NULL); ent1->assign(cfg0); assert (!memcmp(cfg0.m_initiator.get_dst_mac_addr() @@ -181,6 +192,24 @@ TEST_F(basic_client_cfg, test1) { ent1->assign(cfg0); assert (!memcmp(cfg0.m_responder.get_dst_mac_addr() , mac3.GetConstBuffer(), ETHER_ADDR_LEN)); - + } +// simulation testing of MAC based client config +// basic_* tests are checked for memory leaks with valgrind. When running yaml file load/parse, test suite name +// should not start with basic_ +TEST_F(client_cfg, test2) { + CTestBasic t1; + CParserOption * po =&CGlobalInfo::m_options; + + po->reset(); + po->preview.setVMode(3); + po->preview.setFileWrite(true); + po->cfg_file = "cap2/dns.yaml"; + po->out_file = "exp/client_cfg_dns"; + po->client_cfg_file = "cap2/cluster_example.yaml"; + + bool res = t1.init(); + + EXPECT_EQ_UINT32(1, res?1:0)<< "pass"; +} -- cgit 1.2.3-korg