client config gtest 11/4011/1
authorIdo Barnea <[email protected]>
Tue, 22 Nov 2016 16:03:52 +0000 (18:03 +0200)
committerIdo Barnea <[email protected]>
Tue, 22 Nov 2016 16:03:52 +0000 (18:03 +0200)
Signed-off-by: Ido Barnea <[email protected]>
linux/ws_main.py
src/bp_sim.h
src/gtest/client_cfg_test.cpp [new file with mode: 0644]
src/trex_client_config.cpp
src/trex_client_config.h

index 528d557..c989bb5 100755 (executable)
@@ -97,6 +97,7 @@ bp_sim_gtest = SrcGroup(dir='src',
         src_list=[
              'bp_gtest.cpp',
              'gtest/tuple_gen_test.cpp',
+             'gtest/client_cfg_test.cpp',
              'gtest/nat_test.cpp',
              'gtest/trex_stateless_gtest.cpp'
              ])
index 4e3f81f..914a26d 100755 (executable)
@@ -1849,7 +1849,7 @@ typedef std::priority_queue<CGenNode *, std::vector<CGenNode *>,CGenNodeCompare>
 
 
 class CErfIF : public CVirtualIF {
-
+    friend class basic_client_cfg_test1_Test;
 public:
     CErfIF(){
         m_writer=NULL;
diff --git a/src/gtest/client_cfg_test.cpp b/src/gtest/client_cfg_test.cpp
new file mode 100644 (file)
index 0000000..1e84e1d
--- /dev/null
@@ -0,0 +1,186 @@
+/*
+ Ido Barnea
+ Cisco Systems, Inc.
+*/
+
+/*
+Copyright (c) 2016-2016 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 <stdio.h>
+#include "../bp_sim.h"
+#include <common/gtest.h>
+#include <common/basic_utils.h>
+
+class basic_client_cfg : public testing::Test {
+    protected:
+     virtual void SetUp() {
+     }
+     virtual void TearDown() {
+     }
+   public:
+};
+
+TEST_F(basic_client_cfg, test1) {
+    uint32_t ip_start = 0x10010101;
+    uint32_t ip_end = 0x100101ff;
+    uint32_t next_hop_init = 0x01010101;
+    uint32_t next_hop_resp = 0x02020202;
+    uint16_t vlan_init = 5;
+    uint16_t vlan_resp = 7;
+    uint32_t dual_if_mask = 0x01000000;
+    uint32_t test_count = 2;
+    ClientCfgDB cfg_db;
+    ClientCfgDB test_db;
+    ClientCfgEntry cfg_ent;
+    ClientCfgExt cfg_ext;
+    std::vector<ClientCfgCompactEntry *> ent_list;
+    struct CTupleGenPoolYaml c_pool;
+
+    // Create tuple gen, so we can have ip->port translation
+    CTupleGenYamlInfo tg_yam_info;
+    struct CTupleGenPoolYaml s_pool;
+    s_pool.m_ip_start = ip_start;
+    s_pool.m_ip_end = ip_end;
+    s_pool.m_dual_interface_mask = dual_if_mask;
+    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);    
+    
+    std::string tmp_file_name = "/tmp/client_cfg_gtest.yaml";
+    FILE *fd = fopen(tmp_file_name.c_str(), "w");
+
+    if (fd == NULL) {
+        fprintf(stderr, "Failed opening %s file for write\n", tmp_file_name.c_str());
+    }
+
+    // We create config file with 3 groups (Should match 6 ports).
+    cfg_ext.m_initiator.set_next_hop(next_hop_init);
+    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);
+
+    // first group
+    cfg_db.set_vlan(true);
+    cfg_db.add_group(ip_start, cfg_ent);
+
+    //second group
+    cfg_ent.set_params(ip_start + dual_if_mask, ip_end + dual_if_mask
+                       , test_count);
+    cfg_db.add_group(ip_start + dual_if_mask, cfg_ent);
+
+    // third group
+    cfg_ent.set_params(ip_start + 2 * dual_if_mask, ip_end + 2 * dual_if_mask
+                       , test_count);
+    cfg_db.add_group(ip_start + dual_if_mask * 2, cfg_ent);
+
+    cfg_db.dump(fd);
+    fclose(fd);
+    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
+    // we simulate system with only 4 ports
+    int i = 0;
+    for (std::vector<ClientCfgCompactEntry *>::iterator
+             it = ent_list.begin(); it != ent_list.end(); it++) {
+        uint8_t port = (*it)->get_port();
+        uint16_t vlan = (*it)->get_vlan();
+        uint32_t count = (*it)->get_count();
+        uint32_t dst_ip = (*it)->get_dst_ip();
+
+        assert(count == test_count);
+        switch(i) {
+        case 0:
+        case 2:
+            assert(port == i);
+            assert(vlan == vlan_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); 
+            break;
+        default:
+            fprintf(stderr, "Test failed. Too many entries returned\n");
+            exit(1);
+        }
+        i++;
+        delete *it;
+    }
+
+    // Simulate the pre test phase, and hand results to client config
+    CManyIPInfo many_ip;
+    MacAddress mac0, mac1, mac2, mac3;
+    mac0.set(0x0, 0x1, 0x2, 0x3, 0x4, 0);
+    mac1.set(0x0, 0x1, 0x2, 0x3, 0x4, 0x1);
+    mac2.set(0x0, 0x1, 0x2, 0x3, 0x4, 0x2);
+    mac3.set(0x0, 0x1, 0x2, 0x3, 0x4, 0x3);
+    COneIPv4Info ip0_1(next_hop_init, vlan_init, mac0, 0);
+    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;
+
+    ClientCfgEntry *ent0 = test_db.lookup(ip_start);
+    ClientCfgEntry *ent1 = test_db.lookup(ip_start + dual_if_mask);
+
+    assert (ent0 != NULL);
+    ent0->assign(cfg0);
+    assert (!memcmp(cfg0.m_initiator.get_dst_mac_addr()
+                    , mac0.GetConstBuffer(), ETHER_ADDR_LEN));
+    ent0->assign(cfg0);
+    assert (!memcmp(cfg0.m_initiator.get_dst_mac_addr()
+                    , mac1.GetConstBuffer(), ETHER_ADDR_LEN));
+    ent0->assign(cfg0);
+    assert (!memcmp(cfg0.m_responder.get_dst_mac_addr()
+                    , mac2.GetConstBuffer(), ETHER_ADDR_LEN));
+    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()
+                    , mac0.GetConstBuffer(), ETHER_ADDR_LEN));
+    ent1->assign(cfg0);
+    assert (!memcmp(cfg0.m_initiator.get_dst_mac_addr()
+                    , mac1.GetConstBuffer(), ETHER_ADDR_LEN));
+    ent1->assign(cfg0);
+    assert (!memcmp(cfg0.m_responder.get_dst_mac_addr()
+                    , mac2.GetConstBuffer(), ETHER_ADDR_LEN));
+    ent1->assign(cfg0);
+    assert (!memcmp(cfg0.m_responder.get_dst_mac_addr()
+                    , mac3.GetConstBuffer(), ETHER_ADDR_LEN));
+    
+}
+
index 0fd12e0..548d097 100644 (file)
@@ -32,19 +32,19 @@ limitations under the License.
 
 void ClientCfgDirBase::dump(FILE *fd) const {
     if (has_src_mac_addr()) {
-        fprintf(fd, "  src MAC:%s\n", utl_macaddr_to_str(m_src_mac.GetConstBuffer()).c_str());
+        fprintf(fd, "        src_mac: %s\n", utl_macaddr_to_str(m_src_mac.GetConstBuffer()).c_str());
     } else {
-        fprintf(fd, "  No src MAC\n");
+        fprintf(fd, "#       No src MAC\n");
     }
     if (has_dst_mac_addr()) {
-        fprintf(fd, "  dst MAC:%s\n", utl_macaddr_to_str(m_dst_mac.GetConstBuffer()).c_str());
+        fprintf(fd, "        dst_mac: %s\n", utl_macaddr_to_str(m_dst_mac.GetConstBuffer()).c_str());
     } else {
-        fprintf(fd, "  No dst MAC\n");
+        fprintf(fd, "#       No dst MAC\n");
     }
     if (has_vlan()) {
-        fprintf(fd, "  vlan:%d\n", m_vlan);
+        fprintf(fd, "        vlan: %d\n", m_vlan);
     } else {
-        fprintf(fd, "  No vlan\n");
+        fprintf(fd, "#       No vlan\n");
     }
 }
 
@@ -74,20 +74,20 @@ void ClientCfgDirExt::dump(FILE *fd) const {
     ClientCfgDirBase::dump(fd);
 
     if (has_next_hop()) {
-        fprintf(fd, "  next hop:%s\n", ip_to_str(m_next_hop).c_str());
+        fprintf(fd, "        next_hop: %s\n", ip_to_str(m_next_hop).c_str());
     } else {
-        fprintf(fd, "  No next hop\n");
+        fprintf(fd, "#       No next hop\n");
     }
     if (has_ipv6_next_hop()) {
-        fprintf(fd, "  next hop:%s\n", ip_to_str((unsigned char *)m_ipv6_next_hop).c_str());
+        fprintf(fd, "        ipv6_next_hop: %s\n", ip_to_str((unsigned char *)m_ipv6_next_hop).c_str());
     } else {
-        fprintf(fd, "  No IPv6 next hop\n");
+        fprintf(fd, "#       No IPv6 next hop\n");
     }
 
     if (m_resolved_macs.size() > 0) {
-        fprintf(fd, "  Resolved MAC list:\n");
+        fprintf(fd, "#  Resolved MAC list:\n");
         for (int i = 0; i < m_resolved_macs.size(); i++) {
-            fprintf(fd, "   %s\n", utl_macaddr_to_str(m_resolved_macs[i].GetConstBuffer()).c_str());
+            fprintf(fd, "#     %s\n", utl_macaddr_to_str(m_resolved_macs[i].GetConstBuffer()).c_str());
         }
     }
 }
@@ -122,11 +122,10 @@ void ClientCfgBase::update(uint32_t index, const ClientCfgExt *cfg) {
 void
 ClientCfgEntry::dump(FILE *fd) const {
 
-    std::cout << "IP start:       " << ip_to_str(m_ip_start) << "\n";
-    std::cout << "IP end:         " << ip_to_str(m_ip_end) << "\n";
-    fprintf(fd, "count %d\n", m_count);
-
+    fprintf(fd, "-   ip_start : %s\n", ip_to_str(m_ip_start).c_str());
+    fprintf(fd, "    ip_end   : %s\n", ip_to_str(m_ip_end).c_str());
     m_cfg.dump(fd);
+    fprintf(fd, "    count    : %d\n", m_count);
 }
 
 void ClientCfgEntry::set_resolved_macs(CManyIPInfo &pretest_result) {
@@ -163,16 +162,15 @@ void ClientCfgCompactEntry::fill_from_dir(ClientCfgDirExt cfg, uint8_t port_id)
 
 void
 ClientCfgDB::dump(FILE *fd) {
-    fprintf(fd, "**********Client config file start*********\n");
-    fprintf(fd, "vlan: %s is_empty: %s\n"
-            ,m_under_vlan ? "true" : "false"
-            , m_is_empty ? "true" : "false");
+    //fprintf(fd, "#**********Client config file start*********\n");
+    fprintf(fd, "vlan: %s\n", m_under_vlan ? "true" : "false");
+    fprintf(fd, "groups:\n");
 
     for (std::map<uint32_t, ClientCfgEntry>::iterator it = m_groups.begin(); it != m_groups.end(); ++it) {
-        fprintf(fd, "****%s:****\n", ip_to_str(it->first).c_str());
+        fprintf(fd, "****%s:****\n", ip_to_str(it->first).c_str());
         ((ClientCfgEntry)it->second).dump(fd);
     }
-    fprintf(fd, "**********Client config end*********\n");
+    //fprintf(fd, "#**********Client config end*********\n");
 }
 
 void ClientCfgDB::set_resolved_macs(CManyIPInfo &pretest_result) {
@@ -205,8 +203,8 @@ void ClientCfgDB::get_entry_list(std::vector<ClientCfgCompactEntry *> &ret) {
                 if (cfg.m_cfg.m_initiator.need_resolve()) {
                     ClientCfgCompactEntry *init_entry = new ClientCfgCompactEntry();
                     assert(init_entry);
-                    init_entry->m_count = ((ClientCfgEntry)it->second).m_count;
-                    init_entry->fill_from_dir(((ClientCfgEntry)it->second).m_cfg.m_initiator, port);
+                    init_entry->m_count = cfg.m_count;
+                    init_entry->fill_from_dir(cfg.m_cfg.m_initiator, port);
                     ret.push_back(init_entry);
                 }
 
index dbdfd12..257d354 100644 (file)
@@ -190,9 +190,9 @@ class ClientCfgBase {
 
 public:
     virtual void dump (FILE *fd) const {
-        fprintf(fd, "initiator:\n");
+        fprintf(fd, "    initiator :\n");
         m_initiator.dump(fd);
-        fprintf(fd, "responder:\n");
+        fprintf(fd, "    responder :\n");
         m_responder.dump(fd);
     }
     virtual void update(uint32_t index, const ClientCfgExt *cfg);
@@ -205,9 +205,9 @@ public:
 class ClientCfgExt : public ClientCfgBase {
 public:
     virtual void dump (FILE *fd) const {
-        fprintf(fd, "initiator:\n");
+        fprintf(fd, "    initiator:\n");
         m_initiator.dump(fd);
-        fprintf(fd, "responder:\n");
+        fprintf(fd, "    responder:\n");
         m_responder.dump(fd);
     }
 
@@ -254,7 +254,7 @@ class ClientCfgCompactEntry {
  *
  */
 class ClientCfgEntry {
-
+    friend class basic_client_cfg_test1_Test;
 public:
 
     ClientCfgEntry() {
@@ -297,6 +297,14 @@ public:
     uint32_t    m_count;
 
 private:
+    void set_params(uint32_t start, uint32_t end, uint32_t count) { // for tests
+        m_ip_start = start;
+        m_ip_end = end;
+        m_count = count;
+    }
+    void set_cfg(const ClientCfgExt &cfg) {
+        m_cfg = cfg;
+    }
     uint32_t    m_iterator;
 };
 
@@ -305,7 +313,8 @@ private:
  *
  */
 class ClientCfgDB {
-public:
+    friend class basic_client_cfg_test1_Test;
+ public:
 
     ClientCfgDB() {
         m_is_empty    = true;
@@ -314,6 +323,10 @@ public:
         m_tg = NULL;
     }
 
+    ~ClientCfgDB() {
+        m_groups.clear();
+    }
+
     void dump(FILE *fd) ;
 
     /**
@@ -349,7 +362,10 @@ public:
 private:
     void parse_single_group(YAMLParserWrapper &parser, const YAML::Node &node);
     void parse_dir(YAMLParserWrapper &parser, const YAML::Node &node, ClientCfgDirExt &dir);
-
+    void set_vlan(bool val) {m_under_vlan = val;} // for tests
+    void add_group(uint32_t ip, ClientCfgEntry cfg) { // for tests
+        m_groups.insert(std::make_pair(ip, cfg));
+    }
     /**
      * verify the YAML file loaded in valid
      *