test: Mock out interface lookups
This will make it possible to do interface lookups inside of our classes
during testing without depending on real interfaces existing.
Change-Id: I4c273d6961fa4229401fb25a0e5eb06af5b59ca4
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/test/mock_syscall.cpp b/test/mock_syscall.cpp
index 28ebed2..d6338c5 100644
--- a/test/mock_syscall.cpp
+++ b/test/mock_syscall.cpp
@@ -5,6 +5,11 @@
#include <sys/socket.h>
#include <sys/types.h>
+#include <cstring>
+#include <map>
+#include <stdexcept>
+#include <string>
+
#define MAX_IFADDRS 5
int debugging = false;
@@ -28,6 +33,20 @@
return;
}
+std::map<std::string, int> mock_if_nametoindex;
+std::map<int, std::string> mock_if_indextoname;
+
+void mock_addIF(const std::string& name, int idx)
+{
+ if (idx == 0)
+ {
+ throw std::invalid_argument("Bad interface index");
+ }
+
+ mock_if_nametoindex[name] = idx;
+ mock_if_indextoname[idx] = name;
+}
+
void mock_addIP(const char* name, const char* addr, const char* mask,
unsigned int flags)
{
@@ -66,3 +85,30 @@
return -1;
return (0);
}
+
+unsigned if_nametoindex(const char* ifname)
+{
+ auto it = mock_if_nametoindex.find(ifname);
+ if (it == mock_if_nametoindex.end())
+ {
+ errno = ENXIO;
+ return 0;
+ }
+ return it->second;
+}
+
+char* if_indextoname(unsigned ifindex, char* ifname)
+{
+ if (ifindex == 0)
+ {
+ errno = ENXIO;
+ return NULL;
+ }
+ auto it = mock_if_indextoname.find(ifindex);
+ if (it == mock_if_indextoname.end())
+ {
+ // TODO: Return ENXIO once other code is mocked out
+ return std::strcpy(ifname, "invalid");
+ }
+ return std::strcpy(ifname, it->second.c_str());
+}
diff --git a/test/mock_syscall.hpp b/test/mock_syscall.hpp
index d219999..f14bd96 100644
--- a/test/mock_syscall.hpp
+++ b/test/mock_syscall.hpp
@@ -1,4 +1,5 @@
#pragma once
+#include <string>
/** @brief Adds the given interface and addr info
* into the ifaddr list.
@@ -10,3 +11,10 @@
void mock_addIP(const char* name, const char* addr, const char* mask,
unsigned int flags);
+
+/** @brief Adds an address string to index mapping
+ *
+ * @param[in] name - Interface name
+ * @param[in] idx - Interface index
+ */
+void mock_addIF(const std::string& name, int idx);
diff --git a/test/test_ethernet_interface.cpp b/test/test_ethernet_interface.cpp
index 9e611a6..a075423 100644
--- a/test/test_ethernet_interface.cpp
+++ b/test/test_ethernet_interface.cpp
@@ -29,7 +29,7 @@
TestEthernetInterface() :
bus(sdbusplus::bus::new_default()),
manager(bus, "/xyz/openbmc_test/network", "/tmp/"),
- interface(bus, "/xyz/openbmc_test/network/test0", false, manager)
+ interface(makeInterface(bus, manager))
{
setConfDir();
@@ -50,6 +50,13 @@
}
}
+ static EthernetInterface makeInterface(sdbusplus::bus::bus& bus,
+ MockManager& manager)
+ {
+ mock_addIF("test0", 1);
+ return {bus, "/xyz/openbmc_test/network/test0", false, manager};
+ }
+
int countIPObjects()
{
return interface.getAddresses().size();
diff --git a/test/test_neighbor.cpp b/test/test_neighbor.cpp
index 6491b9f..ffb0d5d 100644
--- a/test/test_neighbor.cpp
+++ b/test/test_neighbor.cpp
@@ -1,3 +1,4 @@
+#include "mock_syscall.hpp"
#include "neighbor.hpp"
#include "util.hpp"
@@ -5,7 +6,6 @@
#include <linux/netlink.h>
#include <linux/rtnetlink.h>
#include <net/ethernet.h>
-#include <net/if.h>
#include <cstring>
#include <stdexcept>
@@ -22,6 +22,9 @@
namespace detail
{
+constexpr auto ifStr = "eth0";
+constexpr auto ifIdx = 1;
+
TEST(ParseNeighbor, NotNeighborType)
{
nlmsghdr hdr{};
@@ -58,10 +61,12 @@
TEST(ParseNeighbor, NoAttrs)
{
+ mock_addIF(ifStr, ifIdx);
+
nlmsghdr hdr{};
hdr.nlmsg_type = RTM_NEWNEIGH;
ndmsg msg{};
- msg.ndm_ifindex = if_nametoindex("lo");
+ msg.ndm_ifindex = ifIdx;
ASSERT_NE(0, msg.ndm_ifindex);
std::string data;
data.append(reinterpret_cast<char*>(&msg), sizeof(msg));
@@ -73,10 +78,12 @@
TEST(ParseNeighbor, NoAddress)
{
+ mock_addIF(ifStr, ifIdx);
+
nlmsghdr hdr{};
hdr.nlmsg_type = RTM_NEWNEIGH;
ndmsg msg{};
- msg.ndm_ifindex = if_nametoindex("lo");
+ msg.ndm_ifindex = ifIdx;
ASSERT_NE(0, msg.ndm_ifindex);
ether_addr mac = {{0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa}};
rtattr lladdr{};
@@ -97,13 +104,14 @@
TEST(ParseNeighbor, NoMAC)
{
- constexpr auto ifstr = "lo";
+ mock_addIF(ifStr, ifIdx);
+
nlmsghdr hdr{};
hdr.nlmsg_type = RTM_NEWNEIGH;
ndmsg msg{};
msg.ndm_family = AF_INET;
msg.ndm_state = NUD_PERMANENT;
- msg.ndm_ifindex = if_nametoindex(ifstr);
+ msg.ndm_ifindex = ifIdx;
ASSERT_NE(0, msg.ndm_ifindex);
in_addr addr;
ASSERT_EQ(1, inet_pton(msg.ndm_family, "192.168.10.1", &addr));
@@ -121,7 +129,7 @@
std::vector<NeighborInfo> neighbors;
parseNeighbor(hdr, data, neighbors);
EXPECT_EQ(1, neighbors.size());
- EXPECT_EQ(ifstr, neighbors[0].interface);
+ EXPECT_EQ(ifStr, neighbors[0].interface);
EXPECT_TRUE(neighbors[0].permanent);
EXPECT_FALSE(neighbors[0].mac);
EXPECT_TRUE(equal(addr, std::get<in_addr>(neighbors[0].address)));
@@ -129,13 +137,14 @@
TEST(ParseNeighbor, Full)
{
- constexpr auto ifstr = "lo";
+ mock_addIF(ifStr, ifIdx);
+
nlmsghdr hdr{};
hdr.nlmsg_type = RTM_NEWNEIGH;
ndmsg msg{};
msg.ndm_family = AF_INET6;
msg.ndm_state = NUD_NOARP;
- msg.ndm_ifindex = if_nametoindex(ifstr);
+ msg.ndm_ifindex = ifIdx;
ether_addr mac = {{0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa}};
rtattr lladdr{};
lladdr.rta_len = RTA_LENGTH(sizeof(mac));
@@ -161,7 +170,7 @@
std::vector<NeighborInfo> neighbors;
parseNeighbor(hdr, data, neighbors);
EXPECT_EQ(1, neighbors.size());
- EXPECT_EQ(ifstr, neighbors[0].interface);
+ EXPECT_EQ(ifStr, neighbors[0].interface);
EXPECT_FALSE(neighbors[0].permanent);
EXPECT_TRUE(neighbors[0].mac);
EXPECT_TRUE(equal(mac, *neighbors[0].mac));
diff --git a/test/test_network_manager.cpp b/test/test_network_manager.cpp
index ff0840e..f4de35a 100644
--- a/test/test_network_manager.cpp
+++ b/test/test_network_manager.cpp
@@ -71,6 +71,7 @@
try
{
// Adds the following ip in the getifaddrs list.
+ mock_addIF("igb1", 2);
mock_addIP("igb1", "192.0.2.3", "255.255.255.128",
IFF_UP | IFF_RUNNING);
@@ -92,9 +93,11 @@
{
try
{
+ mock_addIF("igb0", 1);
mock_addIP("igb0", "192.0.2.2", "255.255.255.128",
IFF_UP | IFF_RUNNING);
+ mock_addIF("igb1", 2);
mock_addIP("igb1", "192.0.2.3", "255.255.255.128",
IFF_UP | IFF_RUNNING);
diff --git a/test/test_rtnetlink.cpp b/test/test_rtnetlink.cpp
index ecfa44a..794a0dd 100644
--- a/test/test_rtnetlink.cpp
+++ b/test/test_rtnetlink.cpp
@@ -27,7 +27,6 @@
/** @brief refresh the network objects. */
void refreshObjects()
{
-
if (manager)
{
manager->createChildObjects();
@@ -89,6 +88,7 @@
{
using namespace std::chrono;
// Adds the following ip in the getifaddrs list.
+ mock_addIF("igb5", 6);
mock_addIP("igb5", "127.0.0.1", "255.255.255.128", IFF_UP | IFF_RUNNING);
constexpr auto BUFSIZE = 4096;
std::array<char, BUFSIZE> msgBuf = {0};
diff --git a/test/test_vlan_interface.cpp b/test/test_vlan_interface.cpp
index 7179212..0ff893c 100644
--- a/test/test_vlan_interface.cpp
+++ b/test/test_vlan_interface.cpp
@@ -31,7 +31,7 @@
TestVlanInterface() :
bus(sdbusplus::bus::new_default()),
manager(bus, "/xyz/openbmc_test/network", "/tmp"),
- interface(bus, "/xyz/openbmc_test/network/test0", false, manager)
+ interface(makeInterface(bus, manager))
{
setConfDir();
@@ -45,6 +45,13 @@
}
}
+ static EthernetInterface makeInterface(sdbusplus::bus::bus& bus,
+ MockManager& manager)
+ {
+ mock_addIF("test0", 1);
+ return {bus, "/xyz/openbmc_test/network/test0", false, manager};
+ }
+
void setConfDir()
{
char tmp[] = "/tmp/VlanInterface.XXXXXX";
@@ -54,6 +61,9 @@
void createVlan(VlanId id)
{
+ std::string ifname = "test0.";
+ ifname += std::to_string(id);
+ mock_addIF(ifname.c_str(), 1000 + id);
interface.createVLAN(id);
}