test/ethernet_interface: Improve syscall test coverage
Change-Id: Ia71a030f2e2e19f2cc191992929ef08d0fa917c2
Signed-off-by: William A. Kennington III <wak@google.com>
diff --git a/src/ethernet_interface.cpp b/src/ethernet_interface.cpp
index 498cab8..529bb2a 100644
--- a/src/ethernet_interface.cpp
+++ b/src/ethernet_interface.cpp
@@ -141,7 +141,17 @@
// would be same as parent interface.
if (intfName.find(".") == std::string::npos)
{
- MacAddressIntf::macAddress(getMACAddress(intfName));
+ try
+ {
+ MacAddressIntf::macAddress(getMACAddress(intfName));
+ }
+ catch (const std::exception& e)
+ {
+ auto msg =
+ fmt::format("Failed to get MAC for {}: {}", intfName, e.what());
+ log<level::ERR>(msg.c_str(),
+ entry("INTERFACE=%s", intfName.c_str()));
+ }
}
EthernetInterfaceIntf::ntpServers(
config.map.getValueStrings("Network", "NTP"));
diff --git a/test/mock_ethernet_interface.hpp b/test/mock_ethernet_interface.hpp
index 5e21170..1f72486 100644
--- a/test/mock_ethernet_interface.hpp
+++ b/test/mock_ethernet_interface.hpp
@@ -1,7 +1,5 @@
#pragma once
-
#include "ethernet_interface.hpp"
-#include "mock_syscall.hpp"
#include <gmock/gmock.h>
@@ -12,10 +10,9 @@
class MockEthernetInterface : public EthernetInterface
{
public:
- MockEthernetInterface(sdbusplus::bus_t& bus, const std::string& objPath,
- const config::Parser& config, Manager& parent,
- bool emitSignal) :
- EthernetInterface(bus, objPath, config, parent, emitSignal,
+ template <typename... Args>
+ MockEthernetInterface(Args&&... args) :
+ EthernetInterface(std::forward<Args>(args)..., /*emitSignal=*/false,
/*nicEnabled=*/true)
{
}
diff --git a/test/mock_network_manager.hpp b/test/mock_network_manager.hpp
index af26771..9286d0c 100644
--- a/test/mock_network_manager.hpp
+++ b/test/mock_network_manager.hpp
@@ -1,4 +1,5 @@
#pragma once
+#include "config_parser.hpp"
#include "mock_ethernet_interface.hpp"
#include "network_manager.hpp"
#include "util.hpp"
@@ -34,7 +35,7 @@
objPath /= interface;
config::Parser config(config::pathForIntfConf(confDir, interface));
auto intf = std::make_unique<MockEthernetInterface>(
- bus, objPath.string(), config, *this, true);
+ bus, objPath.string(), config, *this);
intf->createIPAddressObjects();
intf->createStaticNeighborObjects();
intf->loadNameServers(config);
diff --git a/test/mock_syscall.cpp b/test/mock_syscall.cpp
index e4101a3..349a79a 100644
--- a/test/mock_syscall.cpp
+++ b/test/mock_syscall.cpp
@@ -49,34 +49,40 @@
std::map<int, std::queue<std::string>> mock_rtnetlinks;
-std::map<std::string, int> mock_if_nametoindex;
+struct MockInfo
+{
+ unsigned idx;
+ unsigned flags;
+ std::optional<ether_addr> mac;
+ std::optional<unsigned> mtu;
+};
+
+std::map<std::string, MockInfo> mock_if;
std::map<int, std::string> mock_if_indextoname;
-std::map<std::string, ether_addr> mock_macs;
void mock_clear()
{
mock_ifaddrs = nullptr;
ifaddr_count = 0;
mock_rtnetlinks.clear();
- mock_if_nametoindex.clear();
+ mock_if.clear();
mock_if_indextoname.clear();
- mock_macs.clear();
}
-void mock_addIF(const std::string& name, int idx, const ether_addr& mac)
+void mock_addIF(const std::string& name, unsigned idx, unsigned flags,
+ std::optional<ether_addr> mac, std::optional<unsigned> mtu)
{
if (idx == 0)
{
throw std::invalid_argument("Bad interface index");
}
- mock_if_nametoindex[name] = idx;
- mock_if_indextoname[idx] = name;
- mock_macs[name] = mac;
+ mock_if.emplace(
+ name, MockInfo{.idx = idx, .flags = flags, .mac = mac, .mtu = mtu});
+ mock_if_indextoname.emplace(idx, name);
}
-void mock_addIP(const char* name, const char* addr, const char* mask,
- unsigned int flags)
+void mock_addIP(const char* name, const char* addr, const char* mask)
{
struct ifaddrs* ifaddr = &mock_ifaddr_storage[ifaddr_count].ifaddr;
@@ -95,7 +101,7 @@
ifaddr->ifa_next = nullptr;
ifaddr->ifa_name = const_cast<char*>(name);
- ifaddr->ifa_flags = flags;
+ ifaddr->ifa_flags = 0;
ifaddr->ifa_addr = reinterpret_cast<struct sockaddr*>(in);
ifaddr->ifa_netmask = reinterpret_cast<struct sockaddr*>(mask_in);
ifaddr->ifa_data = nullptr;
@@ -135,10 +141,11 @@
return 0;
}
- for (const auto& [name, idx] : mock_if_nametoindex)
+ for (const auto& [name, i] : mock_if)
{
ifinfomsg info{};
- info.ifi_index = idx;
+ info.ifi_index = i.idx;
+ info.ifi_flags = i.flags;
nlmsghdr hdr{};
hdr.nlmsg_len = NLMSG_LENGTH(sizeof(info));
hdr.nlmsg_type = RTM_NEWLINK;
@@ -181,13 +188,13 @@
unsigned if_nametoindex(const char* ifname)
{
- auto it = mock_if_nametoindex.find(ifname);
- if (it == mock_if_nametoindex.end())
+ auto it = mock_if.find(ifname);
+ if (it == mock_if.end())
{
errno = ENXIO;
return 0;
}
- return it->second;
+ return it->second.idx;
}
char* if_indextoname(unsigned ifindex, char* ifname)
@@ -208,16 +215,49 @@
void* data = va_arg(vl, void*);
va_end(vl);
+ auto req = reinterpret_cast<ifreq*>(data);
if (request == SIOCGIFHWADDR)
{
- auto req = reinterpret_cast<ifreq*>(data);
- auto it = mock_macs.find(req->ifr_name);
- if (it == mock_macs.end())
+ auto it = mock_if.find(req->ifr_name);
+ if (it == mock_if.end())
{
errno = ENXIO;
return -1;
}
- std::memcpy(req->ifr_hwaddr.sa_data, &it->second, sizeof(it->second));
+ if (!it->second.mac)
+ {
+ errno = EOPNOTSUPP;
+ return -1;
+ }
+ std::memcpy(req->ifr_hwaddr.sa_data, &*it->second.mac,
+ sizeof(*it->second.mac));
+ return 0;
+ }
+ else if (request == SIOCGIFFLAGS)
+ {
+ auto it = mock_if.find(req->ifr_name);
+ if (it == mock_if.end())
+ {
+ errno = ENXIO;
+ return -1;
+ }
+ req->ifr_flags = it->second.flags;
+ return 0;
+ }
+ else if (request == SIOCGIFMTU)
+ {
+ auto it = mock_if.find(req->ifr_name);
+ if (it == mock_if.end())
+ {
+ errno = ENXIO;
+ return -1;
+ }
+ if (!it->second.mtu)
+ {
+ errno = EOPNOTSUPP;
+ return -1;
+ }
+ req->ifr_mtu = *it->second.mtu;
return 0;
}
diff --git a/test/mock_syscall.hpp b/test/mock_syscall.hpp
index 74a693e..8d51e0f 100644
--- a/test/mock_syscall.hpp
+++ b/test/mock_syscall.hpp
@@ -1,6 +1,7 @@
#pragma once
#include <net/ethernet.h>
+#include <optional>
#include <string>
/** @brief Clears out the interfaces and IPs configured for mocking
@@ -15,8 +16,7 @@
* @param[in] flags - Interface flags.
*/
-void mock_addIP(const char* name, const char* addr, const char* mask,
- unsigned int flags);
+void mock_addIP(const char* name, const char* addr, const char* mask);
/** @brief Adds an address string to index mapping and MAC mapping
*
@@ -24,5 +24,6 @@
* @param[in] idx - Interface index
* @param[in] mac - Interface MAC address
*/
-void mock_addIF(const std::string& name, int idx,
- const ether_addr& mac = ether_addr{});
+void mock_addIF(const std::string& name, unsigned idx, unsigned flags = 0,
+ std::optional<ether_addr> mac = std::nullopt,
+ std::optional<unsigned> mtu = std::nullopt);
diff --git a/test/test_ethernet_interface.cpp b/test/test_ethernet_interface.cpp
index 497eaa0..ad30c0a 100644
--- a/test/test_ethernet_interface.cpp
+++ b/test/test_ethernet_interface.cpp
@@ -39,15 +39,13 @@
{
}
- static constexpr ether_addr mac{0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
-
static MockEthernetInterface makeInterface(sdbusplus::bus_t& bus,
MockManager& manager)
{
mock_clear();
- mock_addIF("test0", 1, mac);
+ mock_addIF("test0", /*idx=*/1);
return {bus, "/xyz/openbmc_test/network/test0", config::Parser(),
- manager, true};
+ manager};
}
int countIPObjects()
@@ -92,10 +90,28 @@
}
};
+TEST_F(TestEthernetInterface, Fields)
+{
+ EXPECT_EQ(0, interface.mtu());
+ EXPECT_EQ("", interface.macAddress());
+ EXPECT_FALSE(interface.linkUp());
+
+ constexpr unsigned idx = 2;
+ constexpr ether_addr mac{0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
+ constexpr unsigned mtu = 150;
+
+ mock_addIF("test1", idx, IFF_RUNNING, mac, mtu);
+ MockEthernetInterface intf(bus, "/xyz/openbmc_test/network/test1",
+ config::Parser(), manager);
+
+ EXPECT_EQ(mtu, intf.mtu());
+ EXPECT_EQ(mac_address::toString(mac), intf.macAddress());
+ EXPECT_TRUE(intf.linkUp());
+}
+
TEST_F(TestEthernetInterface, NoIPaddress)
{
EXPECT_EQ(countIPObjects(), 0);
- EXPECT_EQ(mac_address::toString(mac), interface.macAddress());
}
TEST_F(TestEthernetInterface, AddIPAddress)
diff --git a/test/test_netlink.cpp b/test/test_netlink.cpp
index b3538f2..71be8e9 100644
--- a/test/test_netlink.cpp
+++ b/test/test_netlink.cpp
@@ -298,7 +298,7 @@
mock_clear();
for (size_t i = 0; i < ifs; ++i)
{
- mock_addIF("eth" + std::to_string(i), 1 + i);
+ mock_addIF(fmt::format("eth{}", i), /*idx=*/1 + i);
}
size_t cbCalls = 0;
diff --git a/test/test_network_manager.cpp b/test/test_network_manager.cpp
index 3d4cee8..a607bb7 100644
--- a/test/test_network_manager.cpp
+++ b/test/test_network_manager.cpp
@@ -19,6 +19,8 @@
namespace network
{
+using ::testing::Key;
+using ::testing::UnorderedElementsAre;
namespace fs = std::filesystem;
class TestNetworkManager : public stdplus::gtest::TestWithTmp
@@ -50,15 +52,13 @@
mock_clear();
// 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);
+ mock_addIF("igb1", /*idx=*/2);
+ mock_addIP("igb1", "192.0.2.3", "255.255.255.128");
// Now create the interfaces which will call the mocked getifaddrs
// which returns the above interface detail.
createInterfaces();
- EXPECT_EQ(1, manager.getInterfaces().size());
- EXPECT_NE(manager.getInterfaces().end(),
- manager.getInterfaces().find("igb1"));
+ EXPECT_THAT(manager.getInterfaces(), UnorderedElementsAre(Key("igb1")));
}
// getifaddrs returns two interfaces.
@@ -66,18 +66,14 @@
{
mock_clear();
- 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);
+ mock_addIF("igb0", /*idx=*/1);
+ mock_addIP("igb0", "192.0.2.2", "255.255.255.128");
+ mock_addIF("igb1", /*idx=*/2);
+ mock_addIP("igb1", "192.0.2.3", "255.255.255.128");
createInterfaces();
- EXPECT_EQ(2, manager.getInterfaces().size());
- EXPECT_NE(manager.getInterfaces().end(),
- manager.getInterfaces().find("igb0"));
- EXPECT_NE(manager.getInterfaces().end(),
- manager.getInterfaces().find("igb1"));
+ EXPECT_THAT(manager.getInterfaces(),
+ UnorderedElementsAre(Key("igb0"), Key("igb1")));
}
} // namespace network
} // namespace phosphor
diff --git a/test/test_rtnetlink.cpp b/test/test_rtnetlink.cpp
index 21aaca3..b11100f 100644
--- a/test/test_rtnetlink.cpp
+++ b/test/test_rtnetlink.cpp
@@ -57,8 +57,8 @@
using namespace std::chrono;
mock_clear();
// 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);
+ mock_addIF("igb5", /*idx=*/6);
+ mock_addIP("igb5", "127.0.0.1", "255.255.255.128");
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 c4734b1..9c3a1ea 100644
--- a/test/test_vlan_interface.cpp
+++ b/test/test_vlan_interface.cpp
@@ -40,13 +40,13 @@
MockManager& manager)
{
mock_clear();
- mock_addIF("test0", 1);
+ mock_addIF("test0", /*idx=*/1);
return {bus,
"/xyz/openbmc_test/network/test0",
config::Parser(),
manager,
- false,
- true};
+ /*emitSignals=*/false,
+ /*nicEnabled=*/true};
}
void createVlan(VlanId id)