proxygen
MacAddressTest.cpp
Go to the documentation of this file.
1 /*
2  * Copyright 2014-present Facebook, Inc.
3  *
4  * Licensed under the Apache License, Version 2.0 (the "License");
5  * you may not use this file except in compliance with the License.
6  * You may obtain a copy of the License at
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
10  * Unless required by applicable law or agreed to in writing, software
11  * distributed under the License is distributed on an "AS IS" BASIS,
12  * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13  * See the License for the specific language governing permissions and
14  * limitations under the License.
15  */
16 
17 #include <folly/MacAddress.h>
18 #include <folly/Format.h>
19 #include <folly/IPAddressV6.h>
21 
22 using folly::IPAddressV6;
23 using folly::MacAddress;
24 using folly::StringPiece;
25 
26 void testMAC(const std::string& str, uint64_t expectedHBO) {
27  SCOPED_TRACE(str);
28  MacAddress addr(str);
29  // Make sure parsing returned the expected value.
30  EXPECT_EQ(expectedHBO, addr.u64HBO());
31 
32  // Perform additional checks on the MacAddress
33 
34  // Check using operator==()
35  EXPECT_EQ(MacAddress::fromHBO(expectedHBO), addr);
36  // Check using operator==() when passing in non-zero padding bytes
37  EXPECT_EQ(MacAddress::fromHBO(expectedHBO | 0xa5a5000000000000), addr);
38 
39  // Similar checks after converting to network byte order
40  uint64_t expectedNBO = folly::Endian::big(expectedHBO);
41  EXPECT_EQ(expectedNBO, addr.u64NBO());
42  EXPECT_EQ(MacAddress::fromNBO(expectedNBO), addr);
43  uint64_t nboWithPad = folly::Endian::big(expectedHBO | 0xa5a5000000000000);
44  EXPECT_EQ(MacAddress::fromNBO(nboWithPad), addr);
45 
46  // Check they value returned by bytes()
47  uint8_t expectedBytes[8];
48  memcpy(expectedBytes, &expectedNBO, 8);
49  for (int n = 0; n < 6; ++n) {
50  EXPECT_EQ(expectedBytes[n + 2], addr.bytes()[n]);
51  }
52 }
53 
55  testMAC("12:34:56:78:9a:bc", 0x123456789abc);
56  testMAC("00-11-22-33-44-55", 0x1122334455);
57  testMAC("abcdef123456", 0xabcdef123456);
58  testMAC("1:2:3:4:5:6", 0x010203040506);
59  testMAC("0:0:0:0:0:0", 0);
60  testMAC("0:0:5e:0:1:1", 0x00005e000101);
61 
62  EXPECT_THROW(MacAddress(""), std::invalid_argument);
63  EXPECT_THROW(MacAddress("0"), std::invalid_argument);
64  EXPECT_THROW(MacAddress("12:34"), std::invalid_argument);
65  EXPECT_THROW(MacAddress("12:3"), std::invalid_argument);
66  EXPECT_THROW(MacAddress("12:"), std::invalid_argument);
67  EXPECT_THROW(MacAddress("12:x4:56:78:9a:bc"), std::invalid_argument);
68  EXPECT_THROW(MacAddress("12x34:56:78:9a:bc"), std::invalid_argument);
69  EXPECT_THROW(MacAddress("12:34:56:78:9a:bc:de"), std::invalid_argument);
70  EXPECT_THROW(MacAddress("12:34:56:78:9a:bcde"), std::invalid_argument);
71  EXPECT_THROW(MacAddress("12:34:56:78:9a:bc "), std::invalid_argument);
72  EXPECT_THROW(MacAddress(" 12:34:56:78:9a:bc"), std::invalid_argument);
73  EXPECT_THROW(MacAddress("12:34:56:78:-1:bc"), std::invalid_argument);
74 }
75 
76 void testFromBinary(const char* str, uint64_t expectedHBO) {
77  StringPiece bin(str, 6);
78  auto mac = MacAddress::fromBinary(bin);
79  SCOPED_TRACE(mac.toString());
80  EXPECT_EQ(expectedHBO, mac.u64HBO());
81 }
82 
83 TEST(MacAddress, fromBinary) {
84  testFromBinary("\0\0\0\0\0\0", 0);
85  testFromBinary("\x12\x34\x56\x78\x9a\xbc", 0x123456789abc);
86  testFromBinary("\x11\x22\x33\x44\x55\x66", 0x112233445566);
87 
88  StringPiece empty("");
89  EXPECT_THROW(MacAddress::fromBinary(empty), std::invalid_argument);
90  StringPiece tooShort("\x11", 1);
91  EXPECT_THROW(MacAddress::fromBinary(tooShort), std::invalid_argument);
92  StringPiece tooLong("\x11\x22\x33\x44\x55\x66\x77", 7);
93  EXPECT_THROW(MacAddress::fromBinary(tooLong), std::invalid_argument);
94 }
95 
97  EXPECT_EQ(
98  "12:34:56:78:9a:bc", MacAddress::fromHBO(0x123456789abc).toString());
99  EXPECT_EQ("12:34:56:78:9a:bc", MacAddress("12:34:56:78:9a:bc").toString());
100  EXPECT_EQ("01:23:45:67:89:ab", MacAddress("01-23-45-67-89-ab").toString());
101  EXPECT_EQ("01:23:45:67:89:ab", MacAddress("0123456789ab").toString());
102 }
103 
104 TEST(MacAddress, attributes) {
105  EXPECT_TRUE(MacAddress("ff:ff:ff:ff:ff:ff").isBroadcast());
106  EXPECT_FALSE(MacAddress("7f:ff:ff:ff:ff:ff").isBroadcast());
107  EXPECT_FALSE(MacAddress("7f:ff:ff:ff:ff:fe").isBroadcast());
108  EXPECT_FALSE(MacAddress("00:00:00:00:00:00").isBroadcast());
109  EXPECT_TRUE(MacAddress::fromNBO(0xffffffffffffffffU).isBroadcast());
110 
111  EXPECT_TRUE(MacAddress("ff:ff:ff:ff:ff:ff").isMulticast());
112  EXPECT_TRUE(MacAddress("01:00:00:00:00:00").isMulticast());
113  EXPECT_FALSE(MacAddress("00:00:00:00:00:00").isMulticast());
114  EXPECT_FALSE(MacAddress("fe:ff:ff:ff:ff:ff").isMulticast());
115  EXPECT_FALSE(MacAddress("00:00:5e:00:01:01").isMulticast());
116 
117  EXPECT_FALSE(MacAddress("ff:ff:ff:ff:ff:ff").isUnicast());
118  EXPECT_FALSE(MacAddress("01:00:00:00:00:00").isUnicast());
119  EXPECT_TRUE(MacAddress("00:00:00:00:00:00").isUnicast());
120  EXPECT_TRUE(MacAddress("fe:ff:ff:ff:ff:ff").isUnicast());
121  EXPECT_TRUE(MacAddress("00:00:5e:00:01:01").isUnicast());
122 
123  EXPECT_TRUE(MacAddress("ff:ff:ff:ff:ff:ff").isLocallyAdministered());
124  EXPECT_TRUE(MacAddress("02:00:00:00:00:00").isLocallyAdministered());
125  EXPECT_FALSE(MacAddress("01:00:00:00:00:00").isLocallyAdministered());
126  EXPECT_FALSE(MacAddress("00:00:00:00:00:00").isLocallyAdministered());
127  EXPECT_FALSE(MacAddress("fd:ff:ff:ff:ff:ff").isLocallyAdministered());
128  EXPECT_TRUE(MacAddress("fe:ff:ff:ff:ff:ff").isLocallyAdministered());
129  EXPECT_FALSE(MacAddress("00:00:5e:00:01:01").isLocallyAdministered());
130  EXPECT_TRUE(MacAddress("02:12:34:56:78:9a").isLocallyAdministered());
131 }
132 
133 TEST(MacAddress, createMulticast) {
134  EXPECT_EQ(
135  MacAddress("33:33:00:01:00:03"),
136  MacAddress::createMulticast(IPAddressV6("ff02:dead:beef::1:3")));
137  EXPECT_EQ(
138  MacAddress("33:33:12:34:56:78"),
139  MacAddress::createMulticast(IPAddressV6("ff02::abcd:1234:5678")));
140 }
141 
142 void testCmp(const char* str1, const char* str2) {
143  SCOPED_TRACE(folly::sformat("{} < {}", str1, str2));
144  MacAddress m1(str1);
145  MacAddress m2(str2);
146 
147  // Test the comparison operators
148  EXPECT_TRUE(m1 < m2);
149  EXPECT_FALSE(m1 < m1);
150  EXPECT_TRUE(m1 <= m2);
151  EXPECT_TRUE(m2 > m1);
152  EXPECT_TRUE(m2 >= m1);
153  EXPECT_TRUE(m1 != m2);
154  EXPECT_TRUE(m1 == (m1));
155  EXPECT_FALSE(m1 == m2);
156 
157  // Also test the copy constructor and assignment operator
158  MacAddress copy(m1);
159  EXPECT_EQ(copy, m1);
160  copy = m2;
161  EXPECT_EQ(copy, m2);
162 }
163 
165  testCmp("00:00:00:00:00:00", "00:00:00:00:00:01");
166  testCmp("00:00:00:00:00:01", "00:00:00:00:00:02");
167  testCmp("01:00:00:00:00:00", "02:00:00:00:00:00");
168  testCmp("00:00:00:00:00:01", "00:00:00:00:01:00");
169 }
170 
171 TEST(MacAddress, hash) {
172  EXPECT_EQ(
173  std::hash<MacAddress>()(MacAddress("00:11:22:33:44:55")),
174  std::hash<MacAddress>()(MacAddress("00-11-22-33-44-55")));
175  EXPECT_NE(
176  std::hash<MacAddress>()(MacAddress("00:11:22:33:44:55")),
177  std::hash<MacAddress>()(MacAddress("00:11:22:33:44:56")));
178 }
size_t parse(const char *buf, size_t len)
Definition: test.c:1591
folly::StringPiece toString(StateEnum state)
Definition: State.cpp:16
#define EXPECT_THROW(statement, expected_exception)
Definition: gtest.h:1843
void testCmp(const char *str1, const char *str2)
std::string sformat(StringPiece fmt, Args &&...args)
Definition: Format.h:280
#define EXPECT_EQ(val1, val2)
Definition: gtest.h:1922
uint64_t u64NBO() const
Definition: MacAddress.h:110
void testMAC(const std::string &str, uint64_t expectedHBO)
#define SCOPED_TRACE(message)
Definition: gtest.h:2115
TEST(MacAddress, parse)
constexpr std::decay< T >::type copy(T &&value) noexcept(noexcept(typename std::decay< T >::type(std::forward< T >(value))))
Definition: Utility.h:72
const uint8_t * bytes() const
Definition: MacAddress.h:100
constexpr auto empty(C const &c) -> decltype(c.empty())
Definition: Access.h:55
static T big(T x)
Definition: Bits.h:259
ordering
Definition: Ordering.h:21
void testFromBinary(const char *str, uint64_t expectedHBO)
#define EXPECT_TRUE(condition)
Definition: gtest.h:1859
uint64_t u64HBO() const
Definition: MacAddress.h:122
const char * string
Definition: Conv.cpp:212
#define EXPECT_NE(val1, val2)
Definition: gtest.h:1926
#define EXPECT_FALSE(condition)
Definition: gtest.h:1862
Range< const char * > StringPiece
ThreadPoolListHook * addr