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