xref: /openbmc/phosphor-networkd/test/test_util.cpp (revision 186099d1d95a19768f42427681cb3212796f8e52)
1 #include "util.hpp"
2 
3 #include <arpa/inet.h>
4 #include <fmt/chrono.h>
5 #include <netinet/in.h>
6 
7 #include <charconv>
8 #include <cstddef>
9 #include <cstring>
10 #include <stdexcept>
11 #include <string>
12 #include <string_view>
13 #include <xyz/openbmc_project/Common/error.hpp>
14 
15 #include <gmock/gmock.h>
16 #include <gtest/gtest.h>
17 
18 namespace phosphor
19 {
20 namespace network
21 {
22 
23 using namespace std::literals;
24 using InternalFailure =
25     sdbusplus::xyz::openbmc_project::Common::Error::InternalFailure;
26 class TestUtil : public testing::Test
27 {
28   public:
29     TestUtil()
30     {
31         // Empty
32     }
33 };
34 
35 TEST_F(TestUtil, AddrFromBuf)
36 {
37     std::string tooSmall(1, 'a');
38     std::string tooLarge(24, 'a');
39 
40     struct in_addr ip1;
41     EXPECT_EQ(1, inet_pton(AF_INET, "192.168.10.1", &ip1));
42     std::string_view buf1(reinterpret_cast<char*>(&ip1), sizeof(ip1));
43     InAddrAny res1 = addrFromBuf(AF_INET, buf1);
44     EXPECT_EQ(0, memcmp(&ip1, &std::get<struct in_addr>(res1), sizeof(ip1)));
45     EXPECT_THROW(addrFromBuf(AF_INET, tooSmall), std::runtime_error);
46     EXPECT_THROW(addrFromBuf(AF_INET, tooLarge), std::runtime_error);
47     EXPECT_THROW(addrFromBuf(AF_UNSPEC, buf1), std::invalid_argument);
48 
49     struct in6_addr ip2;
50     EXPECT_EQ(1, inet_pton(AF_INET6, "fdd8:b5ad:9d93:94ee::2:1", &ip2));
51     std::string_view buf2(reinterpret_cast<char*>(&ip2), sizeof(ip2));
52     InAddrAny res2 = addrFromBuf(AF_INET6, buf2);
53     EXPECT_EQ(0, memcmp(&ip2, &std::get<struct in6_addr>(res2), sizeof(ip2)));
54     EXPECT_THROW(addrFromBuf(AF_INET6, tooSmall), std::runtime_error);
55     EXPECT_THROW(addrFromBuf(AF_INET6, tooLarge), std::runtime_error);
56     EXPECT_THROW(addrFromBuf(AF_UNSPEC, buf2), std::invalid_argument);
57 }
58 
59 TEST_F(TestUtil, IpValidation)
60 {
61     EXPECT_TRUE(isValidIP(AF_INET, "0.0.0.0"));
62     EXPECT_TRUE(isValidIP("0.0.0.0"));
63 
64     EXPECT_TRUE(isValidIP(AF_INET, "9.3.185.83"));
65 
66     EXPECT_FALSE(isValidIP(AF_INET, "9.3.185.a"));
67     EXPECT_FALSE(isValidIP("9.3.185.a"));
68 
69     EXPECT_FALSE(isValidIP(AF_INET, "9.3.a.83"));
70 
71     EXPECT_FALSE(isValidIP(AF_INET, "x.x.x.x"));
72 
73     EXPECT_TRUE(isValidIP(AF_INET6, "0:0:0:0:0:0:0:0"));
74     EXPECT_TRUE(isValidIP("0:0:0:0:0:0:0:0"));
75 
76     EXPECT_TRUE(isValidIP(AF_INET6, "1:0:0:0:0:0:0:8"));
77 
78     EXPECT_TRUE(isValidIP(AF_INET6, "1::8"));
79 
80     EXPECT_TRUE(isValidIP(AF_INET6, "0:0:0:0:0:FFFF:204.152.189.116"));
81 
82     EXPECT_TRUE(isValidIP(AF_INET6, "::ffff:204.152.189.116"));
83 
84     EXPECT_TRUE(isValidIP(AF_INET6, "a:0:0:0:0:FFFF:204.152.189.116"));
85 
86     EXPECT_TRUE(isValidIP(AF_INET6, "1::8"));
87 }
88 
89 TEST_F(TestUtil, InterfaceToUbootEthAddr)
90 {
91     EXPECT_EQ(std::nullopt, interfaceToUbootEthAddr("et"));
92     EXPECT_EQ(std::nullopt, interfaceToUbootEthAddr("eth"));
93     EXPECT_EQ(std::nullopt, interfaceToUbootEthAddr("sit0"));
94     EXPECT_EQ(std::nullopt, interfaceToUbootEthAddr("ethh0"));
95     EXPECT_EQ(std::nullopt, interfaceToUbootEthAddr("eth0h"));
96     EXPECT_EQ("ethaddr", interfaceToUbootEthAddr("eth0"));
97     EXPECT_EQ("eth1addr", interfaceToUbootEthAddr("eth1"));
98     EXPECT_EQ("eth5addr", interfaceToUbootEthAddr("eth5"));
99     EXPECT_EQ("eth28addr", interfaceToUbootEthAddr("eth28"));
100 }
101 
102 namespace mac_address
103 {
104 
105 TEST(MacIsEmpty, True)
106 {
107     EXPECT_TRUE(isEmpty({}));
108 }
109 
110 TEST(MacIsEmpty, False)
111 {
112     EXPECT_FALSE(isEmpty({1}));
113     EXPECT_FALSE(isEmpty({0, 0, 0, 1}));
114     EXPECT_FALSE(isEmpty({0, 0, 0, 0, 0, 1}));
115 }
116 
117 TEST(MacIsMulticast, True)
118 {
119     EXPECT_TRUE(isMulticast({255, 255, 255, 255, 255, 255}));
120     EXPECT_TRUE(isMulticast({1}));
121 }
122 
123 TEST(MacIsMulticast, False)
124 {
125     EXPECT_FALSE(isMulticast({0, 1, 2, 3, 4, 5}));
126     EXPECT_FALSE(isMulticast({0xfe, 255, 255, 255, 255, 255}));
127 }
128 
129 TEST(MacIsUnicast, True)
130 {
131     EXPECT_TRUE(isUnicast({0, 1, 2, 3, 4, 5}));
132     EXPECT_TRUE(isUnicast({0xfe, 255, 255, 255, 255, 255}));
133 }
134 
135 TEST(MacIsUnicast, False)
136 {
137     EXPECT_FALSE(isUnicast({}));
138     EXPECT_FALSE(isUnicast({1}));
139     EXPECT_FALSE(isUnicast({255, 255, 255, 255, 255, 255}));
140 }
141 
142 TEST(IgnoredInterfaces, Empty)
143 {
144     auto ret = internal::parseInterfaces({});
145     EXPECT_TRUE(ret.empty());
146 
147     ret = internal::parseInterfaces(" ,  ,, ");
148     EXPECT_TRUE(ret.empty());
149 }
150 
151 TEST(IgnoredInterfaces, NotEmpty)
152 {
153     using ::testing::ContainerEq;
154     std::unordered_set<std::string_view> expected = {"eth0"};
155     auto ret = internal::parseInterfaces("eth0");
156     EXPECT_THAT(ret, ContainerEq(expected));
157 
158     expected = {"eth0", "eth1", "bond1", "usb0"};
159     ret = internal::parseInterfaces(" ,eth0, eth1  ,bond1, usb0,,");
160     EXPECT_THAT(ret, ContainerEq(expected));
161 }
162 
163 } // namespace mac_address
164 } // namespace network
165 } // namespace phosphor
166