Skip to content

Commit

Permalink
add testcases
Browse files Browse the repository at this point in the history
  • Loading branch information
a114j0y committed Nov 23, 2024
1 parent 9e928c6 commit 32de4e1
Showing 1 changed file with 157 additions and 0 deletions.
157 changes: 157 additions & 0 deletions tests/mock_tests/fpmsyncd/test_routesync.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,14 @@
#include "fpmsyncd/routesync.h"
#undef private

#include <arpa/inet.h>
#include <linux/rtnetlink.h>
#include <netlink/route/link.h>
#include <netlink/route/nexthop.h>
#include <linux/nexthop.h>

#include <sstream>

using namespace swss;
#define MAX_PAYLOAD 1024

Expand All @@ -26,6 +34,8 @@ class MockRouteSync : public RouteSync
rtattr *[], std::string&,
std::string& , std::string&,
std::string&), (override));
MOCK_METHOD(bool, getIfName, (int, char *, size_t));
MOCK_METHOD(void, deleteNextHopGroup, (uint32_t));
};
class MockFpm : public FpmInterface
{
Expand Down Expand Up @@ -222,6 +232,7 @@ TEST_F(FpmSyncdResponseTest, testEvpn)
return true;
});
m_mockRouteSync.onMsgRaw(nlh);

vector<string> keys;
vector<FieldValueTuple> fieldValues;
app_route_table.getKeys(keys);
Expand All @@ -232,3 +243,149 @@ TEST_F(FpmSyncdResponseTest, testEvpn)
ASSERT_EQ(value.get(), "0xc8");

}

struct nlmsghdr* createNewNextHopMsgHdr(uint32_t id, const char* gateway, int32_t ifindex)
{
// Allocate memory for netlink message
struct nlmsghdr *nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));

// Setup the netlink header
nlh->nlmsg_type = RTM_NEWNEXTHOP;
nlh->nlmsg_flags = NLM_F_REQUEST | NLM_F_CREATE | NLM_F_REPLACE;

// Setup the next-hop message
struct nhmsg *nhm = (struct nhmsg *)NLMSG_DATA(nlh);
nhm->nh_family = AF_INET;

// Calculate current length
int len = NLMSG_LENGTH(sizeof(struct nhmsg));

// Add NHA_ID attribute
struct rtattr *rta = (struct rtattr *)((char *)nlh + len);
rta->rta_type = NHA_ID;
rta->rta_len = RTA_LENGTH(sizeof(uint32_t));
*(uint32_t *)RTA_DATA(rta) = id;
len += RTA_SPACE(sizeof(uint32_t));

// Add gateway if provided
if (gateway) {
rta = (struct rtattr *)((char *)nlh + len);
rta->rta_type = NHA_GATEWAY;
struct in_addr gw_addr;
inet_pton(AF_INET, gateway, &gw_addr);
rta->rta_len = RTA_LENGTH(sizeof(struct in_addr));
memcpy(RTA_DATA(rta), &gw_addr, sizeof(struct in_addr));
len += RTA_SPACE(sizeof(struct in_addr));
}

// Add interface index if provided
if (ifindex != -1) {
rta = (struct rtattr *)((char *)nlh + len);
rta->rta_type = NHA_OIF;
rta->rta_len = RTA_LENGTH(sizeof(int32_t));
*(int32_t *)RTA_DATA(rta) = ifindex;
len += RTA_SPACE(sizeof(int32_t));
}

nlh->nlmsg_len = len;

return nlh;
}

struct nlmsghdr* createDelNextHopMsgHdr(uint32_t id)
{
struct nlmsghdr *nlh = (struct nlmsghdr *)malloc(NLMSG_SPACE(MAX_PAYLOAD));
memset(nlh, 0, NLMSG_SPACE(MAX_PAYLOAD));

nlh->nlmsg_type = RTM_DELNEXTHOP;
nlh->nlmsg_flags = NLM_F_REQUEST;

struct nhmsg *nhm = (struct nhmsg *)NLMSG_DATA(nlh);
nhm->nh_family = AF_INET;

int len = NLMSG_LENGTH(sizeof(struct nhmsg));

struct rtattr *rta = (struct rtattr *)((char *)nlh + len);
rta->rta_type = NHA_ID;
rta->rta_len = RTA_LENGTH(sizeof(uint32_t));
*(uint32_t *)RTA_DATA(rta) = id;
len += RTA_SPACE(sizeof(uint32_t));

nlh->nlmsg_len = len;
return nlh;
}

void printNlMsg(struct nlmsghdr *nlh) {
struct nhmsg *nhm = (struct nhmsg *)NLMSG_DATA(nlh);
struct rtattr *tb[NHA_MAX + 1] = {};

std::cout << "Message info:" << endl;
std::cout << " nlmsg_type: " << nlh->nlmsg_type << endl;
std::cout << " nlmsg_len: " << nlh->nlmsg_len << endl;
std::cout << " nh_family: " << (int)nhm->nh_family << endl;

char* nhm_ptr = (char *)(nhm) + NLMSG_ALIGN(sizeof(struct nhmsg));
struct rtattr* rta;
memcpy(&rta, nhm_ptr, sizeof(struct rtattr));

if (netlink_parse_rtattr(tb, NHA_MAX, rta, nlh->nlmsg_len)) {
std::cout << "Parsed attributes:" << endl;
if (tb[NHA_OIF]) {
int32_t ifindex = *((int32_t *)RTA_DATA(tb[NHA_OIF]));
std::cout << " Found NHA_OIF: " << ifindex << endl;
} else {
std::cout << " NHA_OIF not found" << endl;
}
// ... print other attributes if needed
}
}

TEST_F(FpmSyncdResponseTest, testNewNextHopMsg)
{
struct nlmsghdr *nlh = createNewNextHopMsgHdr(1, "192.168.1.1", 100);

printNlMsg(nlh);

EXPECT_CALL(m_mockRouteSync, getIfName(1, testing::_, IFNAMSIZ))
.WillOnce(testing::DoAll(
testing::Invoke([](int ifindex, char* buf, size_t size) {
strncpy(buf, "Ethernet0", size);
buf[size-1] = '\0';
return true;
})));

m_mockRouteSync.onNextHopMsg(nlh, nlh->nlmsg_len);

shared_ptr<swss::DBConnector> m_app_db;
m_app_db = make_shared<swss::DBConnector>("APPL_DB", 0);
Table app_nhg_table(m_app_db.get(), APP_NEXTHOP_GROUP_TABLE_NAME);
vector<string> keys;
vector<FieldValueTuple> fieldValues;

app_nhg_table.getKeys(keys);
app_nhg_table.get(keys[0], fieldValues);

std::std::cout << "testing --- " << keys.size() << " +++ " << fieldValues.size() << std::endl;

auto nexthop = swss::fvsGetValue(fieldValues, "nexthop", true);
auto ifname = swss::fvsGetValue(fieldValues, "ifname", true);
std::std::cout << "testing --- " << nexthop.value() << ifname.value() << std::endl;

EXPECT_EQ(nexthop.value(), "192.168.1.1");
EXPECT_EQ(ifname.value(), "Ethernet0");

free(nlh);
}

TEST_F(FpmSyncdResponseTest, testDeleteNextHopMsg) {
uint32_t id = 1;
struct nlmsghdr* nlh = createDelNextHopMsgHdr(id);

EXPECT_CALL(m_mockRouteSync, deleteNextHopGroup(id))
.Times(1)
.WillOnce(testing::Return());

m_mockRouteSync.onNextHopMsg(nlh, nlh->nlmsg_len);
free(nlh);
}

0 comments on commit 32de4e1

Please sign in to comment.