xref: /openbmc/phosphor-networkd/test/test_ethernet_interface.cpp (revision b03a760fa265a2f583719d542a617de3e5dfe3e2)
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