1 #include "config_parser.hpp" 2 #include "ipaddress.hpp" 3 #include "mock_ethernet_interface.hpp" 4 #include "test_network_manager.hpp" 5 6 #include <net/if.h> 7 8 #include <sdbusplus/bus.hpp> 9 #include <stdplus/gtest/tmp.hpp> 10 #include <string_view> 11 #include <xyz/openbmc_project/Common/error.hpp> 12 13 #include <gtest/gtest.h> 14 15 namespace phosphor 16 { 17 namespace network 18 { 19 20 using std::literals::string_view_literals::operator""sv; 21 using testing::Key; 22 using testing::UnorderedElementsAre; 23 24 class TestEthernetInterface : public stdplus::gtest::TestWithTmp 25 { 26 public: 27 stdplus::Pinned<sdbusplus::bus_t> bus; 28 std::filesystem::path confDir; 29 TestManager manager; 30 MockEthernetInterface interface; 31 TestEthernetInterface() : 32 bus(sdbusplus::bus::new_default()), confDir(CaseTmpDir()), 33 manager(bus, "/xyz/openbmc_test/network", confDir), 34 interface(makeInterface(bus, manager)) 35 36 { 37 } 38 39 static MockEthernetInterface 40 makeInterface(stdplus::PinnedRef<sdbusplus::bus_t> bus, 41 TestManager& manager) 42 { 43 AllIntfInfo info{InterfaceInfo{.idx = 1, .flags = 0, .name = "test0"}}; 44 return {bus, manager, info, "/xyz/openbmc_test/network"sv, 45 config::Parser()}; 46 } 47 48 auto createIPObject(IP::Protocol addressType, const std::string& ipaddress, 49 uint8_t subnetMask) 50 { 51 return interface.ip(addressType, ipaddress, subnetMask, ""); 52 } 53 54 void setNtpServers() 55 { 56 ServerList ntpServers = {"10.1.1.1", "10.2.2.2", "10.3.3.3"}; 57 interface.EthernetInterfaceIntf::ntpServers(ntpServers); 58 } 59 60 ServerList getNtpServers() 61 { 62 return interface.EthernetInterfaceIntf::ntpServers(); 63 } 64 }; 65 66 TEST_F(TestEthernetInterface, Fields) 67 { 68 EXPECT_EQ(0, interface.mtu()); 69 EXPECT_EQ("", interface.macAddress()); 70 EXPECT_FALSE(interface.linkUp()); 71 72 constexpr ether_addr mac{0x11, 0x22, 0x33, 0x44, 0x55, 0x66}; 73 constexpr unsigned mtu = 150; 74 75 AllIntfInfo info{InterfaceInfo{.idx = 2, 76 .flags = IFF_RUNNING, 77 .name = "test1", 78 .mac = mac, 79 .mtu = mtu}}; 80 MockEthernetInterface intf(bus, manager, info, 81 "/xyz/openbmc_test/network"sv, config::Parser()); 82 83 EXPECT_EQ(mtu, intf.mtu()); 84 EXPECT_EQ(std::to_string(mac), intf.macAddress()); 85 EXPECT_TRUE(intf.linkUp()); 86 } 87 88 TEST_F(TestEthernetInterface, NoIPaddress) 89 { 90 EXPECT_TRUE(interface.addrs.empty()); 91 } 92 93 TEST_F(TestEthernetInterface, AddIPAddress) 94 { 95 createIPObject(IP::Protocol::IPv4, "10.10.10.10", 16); 96 EXPECT_THAT(interface.addrs, UnorderedElementsAre(Key( 97 IfAddr(in_addr{htonl(0x0a0a0a0a)}, 16)))); 98 } 99 100 TEST_F(TestEthernetInterface, AddMultipleAddress) 101 { 102 createIPObject(IP::Protocol::IPv4, "10.10.10.10", 16); 103 createIPObject(IP::Protocol::IPv4, "20.20.20.20", 16); 104 EXPECT_THAT( 105 interface.addrs, 106 UnorderedElementsAre(Key(IfAddr(in_addr{htonl(0x0a0a0a0a)}, 16)), 107 Key(IfAddr(in_addr{htonl(0x14141414)}, 16)))); 108 } 109 110 TEST_F(TestEthernetInterface, DeleteIPAddress) 111 { 112 createIPObject(IP::Protocol::IPv4, "10.10.10.10", 16); 113 createIPObject(IP::Protocol::IPv4, "20.20.20.20", 16); 114 interface.addrs.at(IfAddr(in_addr{htonl(0x0a0a0a0a)}, 16))->delete_(); 115 EXPECT_THAT(interface.addrs, UnorderedElementsAre(Key( 116 IfAddr(in_addr{htonl(0x14141414)}, 16)))); 117 } 118 119 TEST_F(TestEthernetInterface, CheckObjectPath) 120 { 121 auto path = createIPObject(IP::Protocol::IPv4, "10.10.10.10", 16); 122 EXPECT_EQ(path.parent_path(), "/xyz/openbmc_test/network/test0"); 123 EXPECT_EQ(path.filename(), "10.10.10.10/16"); 124 } 125 126 TEST_F(TestEthernetInterface, addStaticNameServers) 127 { 128 ServerList servers = {"9.1.1.1", "9.2.2.2", "9.3.3.3"}; 129 EXPECT_CALL(manager.mockReload, schedule()); 130 interface.staticNameServers(servers); 131 config::Parser parser((confDir / "00-bmc-test0.network").native()); 132 EXPECT_EQ(servers, parser.map.getValueStrings("Network", "DNS")); 133 } 134 135 TEST_F(TestEthernetInterface, getDynamicNameServers) 136 { 137 ServerList servers = {"9.1.1.1", "9.2.2.2", "9.3.3.3"}; 138 EXPECT_CALL(interface, getNameServerFromResolvd()) 139 .WillRepeatedly(testing::Return(servers)); 140 EXPECT_EQ(interface.getNameServerFromResolvd(), servers); 141 } 142 143 TEST_F(TestEthernetInterface, addStaticNTPServers) 144 { 145 ServerList servers = {"10.1.1.1", "10.2.2.2", "10.3.3.3"}; 146 EXPECT_CALL(manager.mockReload, schedule()); 147 interface.staticNTPServers(servers); 148 config::Parser parser((confDir / "00-bmc-test0.network").native()); 149 EXPECT_EQ(servers, parser.map.getValueStrings("Network", "NTP")); 150 } 151 152 TEST_F(TestEthernetInterface, addNTPServers) 153 { 154 using namespace sdbusplus::xyz::openbmc_project::Common::Error; 155 ServerList servers = {"10.1.1.1", "10.2.2.2", "10.3.3.3"}; 156 EXPECT_THROW(interface.ntpServers(servers), NotAllowed); 157 } 158 159 TEST_F(TestEthernetInterface, getNTPServers) 160 { 161 ServerList servers = {"10.1.1.1", "10.2.2.2", "10.3.3.3"}; 162 setNtpServers(); 163 EXPECT_EQ(getNtpServers(), servers); 164 } 165 166 TEST_F(TestEthernetInterface, addGateway) 167 { 168 std::string gateway = "10.3.3.3"; 169 interface.defaultGateway(gateway); 170 EXPECT_EQ(interface.defaultGateway(), gateway); 171 interface.defaultGateway(""); 172 EXPECT_EQ(interface.defaultGateway(), ""); 173 } 174 175 TEST_F(TestEthernetInterface, addGateway6) 176 { 177 std::string gateway6 = "ffff:ffff:ffff:fe80::1"; 178 interface.defaultGateway6(gateway6); 179 EXPECT_EQ(interface.defaultGateway6(), gateway6); 180 interface.defaultGateway6(""); 181 EXPECT_EQ(interface.defaultGateway6(), ""); 182 } 183 184 TEST_F(TestEthernetInterface, DHCPEnabled) 185 { 186 EXPECT_CALL(manager.mockReload, schedule()) 187 .WillRepeatedly(testing::Return()); 188 189 using DHCPConf = EthernetInterfaceIntf::DHCPConf; 190 auto test = [&](DHCPConf conf, bool dhcp4, bool dhcp6, bool ra) { 191 EXPECT_EQ(conf, interface.dhcpEnabled()); 192 EXPECT_EQ(dhcp4, interface.dhcp4()); 193 EXPECT_EQ(dhcp6, interface.dhcp6()); 194 EXPECT_EQ(ra, interface.ipv6AcceptRA()); 195 }; 196 test(DHCPConf::both, /*dhcp4=*/true, /*dhcp6=*/true, /*ra=*/true); 197 198 auto set_test = [&](DHCPConf conf, bool dhcp4, bool dhcp6, bool ra) { 199 EXPECT_EQ(conf, interface.dhcpEnabled(conf)); 200 test(conf, dhcp4, dhcp6, ra); 201 }; 202 set_test(DHCPConf::none, /*dhcp4=*/false, /*dhcp6=*/false, /*ra=*/false); 203 set_test(DHCPConf::v4, /*dhcp4=*/true, /*dhcp6=*/false, /*ra=*/false); 204 set_test(DHCPConf::v6stateless, /*dhcp4=*/false, /*dhcp6=*/false, 205 /*ra=*/true); 206 set_test(DHCPConf::v6, /*dhcp4=*/false, /*dhcp6=*/true, /*ra=*/true); 207 set_test(DHCPConf::v4v6stateless, /*dhcp4=*/true, /*dhcp6=*/false, 208 /*ra=*/true); 209 set_test(DHCPConf::both, /*dhcp4=*/true, /*dhcp6=*/true, /*ra=*/true); 210 211 auto ind_test = [&](DHCPConf conf, bool dhcp4, bool dhcp6, bool ra) { 212 EXPECT_EQ(dhcp4, interface.dhcp4(dhcp4)); 213 EXPECT_EQ(dhcp6, interface.dhcp6(dhcp6)); 214 EXPECT_EQ(ra, interface.ipv6AcceptRA(ra)); 215 test(conf, dhcp4, dhcp6, ra); 216 }; 217 ind_test(DHCPConf::none, /*dhcp4=*/false, /*dhcp6=*/false, /*ra=*/false); 218 ind_test(DHCPConf::v4, /*dhcp4=*/true, /*dhcp6=*/false, /*ra=*/false); 219 ind_test(DHCPConf::v6stateless, /*dhcp4=*/false, /*dhcp6=*/false, 220 /*ra=*/true); 221 ind_test(DHCPConf::v6, /*dhcp4=*/false, /*dhcp6=*/true, /*ra=*/false); 222 set_test(DHCPConf::v6, /*dhcp4=*/false, /*dhcp6=*/true, /*ra=*/true); 223 ind_test(DHCPConf::v4v6stateless, /*dhcp4=*/true, /*dhcp6=*/false, 224 /*ra=*/true); 225 ind_test(DHCPConf::both, /*dhcp4=*/true, /*dhcp6=*/true, /*ra=*/false); 226 set_test(DHCPConf::both, /*dhcp4=*/true, /*dhcp6=*/true, /*ra=*/true); 227 } 228 229 } // namespace network 230 } // namespace phosphor 231