1 #include "config_parser.hpp"
2 #include "network_manager.hpp"
3 #include "mock_syscall.hpp"
4 #include "ipaddress.hpp"
5 
6 #include <gtest/gtest.h>
7 #include <sdbusplus/bus.hpp>
8 
9 #include <arpa/inet.h>
10 #include <net/if.h>
11 #include <netinet/in.h>
12 #include <stdlib.h>
13 
14 #include <exception>
15 #include <fstream>
16 
17 namespace phosphor
18 {
19 namespace network
20 {
21 
22 class TestEthernetInterface : public testing::Test
23 {
24     public:
25 
26         sdbusplus::bus::bus bus;
27         Manager manager;
28         EthernetInterface interface;
29         std::string confDir;
30         TestEthernetInterface()
31             : bus(sdbusplus::bus::new_default()),
32               manager(bus, "/xyz/openbmc_test/network", "/tmp/"),
33               interface(bus, "/xyz/openbmc_test/network/test0", false, manager)
34 
35         {
36             setConfDir();
37         }
38 
39         void setConfDir()
40         {
41             char tmp[] = "/tmp/EthernetInterface.XXXXXX";
42             confDir = mkdtemp(tmp);
43             manager.setConfDir(confDir);
44         }
45 
46         ~TestEthernetInterface()
47         {
48             if(confDir != "")
49             {
50                 fs::remove_all(confDir);
51             }
52         }
53 
54 
55         int countIPObjects()
56         {
57             return interface.getAddresses().size();
58         }
59 
60         bool isIPObjectExist(const std::string& ipaddress)
61         {
62             auto address = interface.getAddresses().find(ipaddress);
63             if (address == interface.getAddresses().end())
64             {
65                 return false;
66             }
67             return true;
68 
69         }
70 
71         bool deleteIPObject(const std::string& ipaddress)
72         {
73             auto address = interface.getAddresses().find(ipaddress);
74             if (address == interface.getAddresses().end())
75             {
76                 return false;
77             }
78             address->second->delete_();
79             return true;
80         }
81 
82         std::string getObjectPath(const std::string& ipaddress,
83                                   uint8_t subnetMask,
84                                   const std::string& gateway)
85         {
86             IP::Protocol addressType = IP::Protocol::IPv4;
87 
88             return interface.generateObjectPath(addressType,
89                                                 ipaddress,
90                                                 subnetMask,
91                                                 gateway);
92         }
93 
94         void createIPObject(IP::Protocol addressType,
95                             const std::string& ipaddress,
96                             uint8_t subnetMask,
97                             const std::string& gateway)
98         {
99             interface.iP(addressType,
100                          ipaddress,
101                          subnetMask,
102                          gateway
103                         );
104 
105         }
106 
107         // Validates if the DNS entries have been correctly processed
108         void validateResolvFile(ServerList values)
109         {
110             // Check whether the entries has been written to resolv.conf
111             fs::path resolvFile = confDir;
112             resolvFile /= "resolv.conf";
113 
114             // Passed in "value" is what is read from the config file
115             interface.writeDNSEntries(values, resolvFile);
116             std::string expectedServers = "### Generated manually via dbus settings ###";
117             expectedServers +=
118                 "nameserver 9.1.1.1nameserver 9.2.2.2nameserver 9.3.3.3";
119 
120             std::string actualServers{};
121             std::fstream stream(resolvFile.string().c_str(), std::fstream::in);
122             for (std::string line; std::getline(stream, line);)
123             {
124                 actualServers += line;
125             }
126             EXPECT_EQ(expectedServers , actualServers);
127         }
128 };
129 
130 TEST_F(TestEthernetInterface, NoIPaddress)
131 {
132     EXPECT_EQ(countIPObjects(), 0);
133 
134 }
135 
136 TEST_F(TestEthernetInterface, AddIPAddress)
137 {
138     IP::Protocol addressType = IP::Protocol::IPv4;
139     createIPObject(addressType, "10.10.10.10", 16, "10.10.10.1");
140     EXPECT_EQ(true, isIPObjectExist("10.10.10.10"));
141 
142 }
143 
144 TEST_F(TestEthernetInterface, AddMultipleAddress)
145 {
146     IP::Protocol addressType = IP::Protocol::IPv4;
147     createIPObject(addressType, "10.10.10.10", 16, "10.10.10.1");
148     createIPObject(addressType, "20.20.20.20", 16, "20.20.20.1");
149     EXPECT_EQ(true, isIPObjectExist("10.10.10.10"));
150     EXPECT_EQ(true, isIPObjectExist("20.20.20.20"));
151 
152 }
153 
154 TEST_F(TestEthernetInterface, DeleteIPAddress)
155 {
156     IP::Protocol addressType = IP::Protocol::IPv4;
157     createIPObject(addressType, "10.10.10.10", 16, "10.10.10.1");
158     createIPObject(addressType, "20.20.20.20", 16, "20.20.20.1");
159     deleteIPObject("10.10.10.10");
160     EXPECT_EQ(false, isIPObjectExist("10.10.10.10"));
161     EXPECT_EQ(true, isIPObjectExist("20.20.20.20"));
162 
163 }
164 
165 TEST_F(TestEthernetInterface, DeleteInvalidIPAddress)
166 {
167     EXPECT_EQ(false, deleteIPObject("10.10.10.10"));
168 }
169 
170 TEST_F(TestEthernetInterface, CheckObjectPath)
171 {
172     std::string ipaddress = "10.10.10.10";
173     uint8_t prefix = 16;
174     std::string gateway = "10.10.10.1";
175 
176     std::string expectedObjectPath = "/xyz/openbmc_test/network/test0/ipv4/";
177     std::stringstream hexId;
178 
179     std::string hashString = ipaddress;
180     hashString += std::to_string(prefix);
181     hashString += gateway;
182 
183 
184     hexId << std::hex << ((std::hash<std::string> {}(
185                                hashString)) & 0xFFFFFFFF);
186     expectedObjectPath += hexId.str();
187 
188     EXPECT_EQ(expectedObjectPath, getObjectPath(ipaddress,
189                                                 prefix,
190                                                 gateway));
191 }
192 
193 TEST_F(TestEthernetInterface, addNameServers)
194 {
195     ServerList servers = {"9.1.1.1","9.2.2.2","9.3.3.3"};
196     interface.nameservers(servers);
197     fs::path filePath = confDir;
198     filePath /= "00-bmc-test0.network";
199     config::Parser parser(filePath.string());
200     config::ReturnCode rc = config::ReturnCode::SUCCESS;
201     config::ValueList values;
202     std::tie(rc, values) = parser.getValues("Network", "DNS");
203     EXPECT_EQ(servers , values);
204 
205     validateResolvFile(values);
206 }
207 
208 TEST_F(TestEthernetInterface, addNTPServers)
209 {
210     ServerList servers = {"10.1.1.1","10.2.2.2","10.3.3.3"};
211     interface.nTPServers(servers);
212     fs::path filePath = confDir;
213     filePath /= "00-bmc-test0.network";
214     config::Parser parser(filePath.string());
215     config::ReturnCode rc = config::ReturnCode::SUCCESS;
216     config::ValueList values;
217     std::tie(rc, values) = parser.getValues("Network", "NTP");
218     EXPECT_EQ(servers , values);
219 }
220 
221 }// namespce network
222 }// namespace phosphor
223