test_netlink: Add basic request test
This adds a basic request / response test for netlink by faking out the
enumeration of network interfaces.
Change-Id: I6a2d4f8e162bb127976a6ea8721f663bce662f18
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/test/mock_syscall.cpp b/test/mock_syscall.cpp
index 280c74d..421dbfe 100644
--- a/test/mock_syscall.cpp
+++ b/test/mock_syscall.cpp
@@ -1,3 +1,5 @@
+#include "util.hpp"
+
#include <arpa/inet.h>
#include <dlfcn.h>
#include <ifaddrs.h>
@@ -123,6 +125,37 @@
}
}
+ssize_t sendmsg_link_dump(std::queue<std::string>& msgs, std::string_view in)
+{
+ const ssize_t ret = in.size();
+ const auto& hdrin = phosphor::copyFrom<nlmsghdr>(in);
+ if (hdrin.nlmsg_type != RTM_GETLINK)
+ {
+ return 0;
+ }
+
+ for (const auto& [name, idx] : mock_if_nametoindex)
+ {
+ ifinfomsg info{};
+ info.ifi_index = idx;
+ nlmsghdr hdr{};
+ hdr.nlmsg_len = NLMSG_LENGTH(sizeof(info));
+ hdr.nlmsg_type = RTM_NEWLINK;
+ hdr.nlmsg_flags = NLM_F_MULTI;
+ auto& out = msgs.emplace(hdr.nlmsg_len, '\0');
+ memcpy(out.data(), &hdr, sizeof(hdr));
+ memcpy(NLMSG_DATA(out.data()), &info, sizeof(info));
+ }
+
+ nlmsghdr hdr{};
+ hdr.nlmsg_len = NLMSG_LENGTH(0);
+ hdr.nlmsg_type = NLMSG_DONE;
+ hdr.nlmsg_flags = NLM_F_MULTI;
+ auto& out = msgs.emplace(hdr.nlmsg_len, '\0');
+ memcpy(out.data(), &hdr, sizeof(hdr));
+ return ret;
+}
+
ssize_t sendmsg_ack(std::queue<std::string>& msgs, std::string_view in)
{
nlmsgerr ack{};
@@ -249,6 +282,12 @@
std::string_view iov(reinterpret_cast<char*>(msg->msg_iov[0].iov_base),
msg->msg_iov[0].iov_len);
+ ret = sendmsg_link_dump(msgs, iov);
+ if (ret != 0)
+ {
+ return ret;
+ }
+
ret = sendmsg_ack(msgs, iov);
if (ret != 0)
{
diff --git a/test/test_netlink.cpp b/test/test_netlink.cpp
index 41cd1ca..8d20c39 100644
--- a/test/test_netlink.cpp
+++ b/test/test_netlink.cpp
@@ -286,6 +286,46 @@
EXPECT_EQ(0, memcmp(&nextbuf, data.data(), sizeof(nextbuf)));
}
+class PerformRequest : public testing::Test
+{
+ public:
+ void doLinkDump(size_t ifs)
+ {
+ mock_clear();
+ for (size_t i = 0; i < ifs; ++i)
+ {
+ mock_addIF("eth" + std::to_string(i), 1 + i);
+ }
+
+ size_t cbCalls = 0;
+ auto cb = [&](const nlmsghdr&, std::string_view) { cbCalls++; };
+ ifinfomsg msg{};
+ netlink::performRequest(NETLINK_ROUTE, RTM_GETLINK, NLM_F_DUMP, msg,
+ cb);
+ EXPECT_EQ(ifs, cbCalls);
+ }
+};
+
+TEST_F(PerformRequest, NoResponse)
+{
+ doLinkDump(0);
+}
+
+TEST_F(PerformRequest, SingleResponse)
+{
+ doLinkDump(1);
+}
+
+TEST_F(PerformRequest, MultiResponse)
+{
+ doLinkDump(3);
+}
+
+TEST_F(PerformRequest, MultiMsg)
+{
+ doLinkDump(1000);
+}
+
} // namespace netlink
} // namespace network
} // namespace phosphor