Create generic method to extract mac address from EUI-64 constructed addresses
[folly.git] / folly / test / IPAddressTest.cpp
1 /*
2  * Copyright 2017 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 <sys/types.h>
18
19 #include <string>
20
21 #include <folly/Bits.h>
22 #include <folly/Format.h>
23 #include <folly/IPAddress.h>
24 #include <folly/MacAddress.h>
25 #include <folly/String.h>
26 #include <folly/detail/IPAddressSource.h>
27 #include <folly/portability/GMock.h>
28 #include <folly/portability/GTest.h>
29
30 using namespace folly;
31 using namespace std;
32 using namespace testing;
33
34 typedef std::vector<uint8_t> ByteVector;
35
36 struct AddressData {
37   std::string address;
38   ByteVector bytes;
39   uint8_t version;
40
41   AddressData(
42       const std::string& address,
43       const ByteVector& bytes,
44       uint8_t version)
45       : address(address), bytes(bytes), version(version) {}
46   AddressData(const std::string& address, uint8_t version)
47       : address(address), bytes(), version(version) {}
48   explicit AddressData(const std::string& address)
49       : address(address), bytes(), version(0) {}
50   AddressData() : address(""), bytes(), version(0) {}
51
52   static in_addr parseAddress4(const std::string& src) {
53     in_addr addr;
54     inet_pton(AF_INET, src.c_str(), &addr);
55     return addr;
56   }
57
58   static in6_addr parseAddress6(const std::string& src) {
59     in6_addr addr;
60     inet_pton(AF_INET6, src.c_str(), &addr);
61     return addr;
62   }
63 };
64
65 struct AddressFlags {
66   std::string address;
67   uint8_t flags;
68   uint8_t version;
69
70   static const uint8_t IS_LOCAL = 1 << 0;
71   static const uint8_t IS_NONROUTABLE = 1 << 1;
72   static const uint8_t IS_PRIVATE = 1 << 2;
73   static const uint8_t IS_ZERO = 1 << 3;
74   static const uint8_t IS_LINK_LOCAL = 1 << 4;
75   static const uint8_t IS_MULTICAST = 1 << 5;
76   static const uint8_t IS_LINK_LOCAL_BROADCAST = 1 << 6;
77
78   AddressFlags(const std::string& addr, uint8_t version, uint8_t flags)
79       : address(addr), flags(flags), version(version) {}
80
81   bool isLoopback() const {
82     return (flags & IS_LOCAL);
83   }
84   bool isNonroutable() const {
85     return (flags & IS_NONROUTABLE);
86   }
87   bool isPrivate() const {
88     return (flags & IS_PRIVATE);
89   }
90   bool isZero() const {
91     return (flags & IS_ZERO);
92   }
93   bool isLinkLocal() const {
94     return (flags & IS_LINK_LOCAL);
95   }
96   bool isLinkLocalBroadcast() const {
97     return (flags & IS_LINK_LOCAL_BROADCAST);
98   }
99 };
100
101 struct MaskData {
102   std::string address;
103   uint8_t mask;
104   std::string subnet;
105   MaskData(const std::string& addr, uint8_t mask, const std::string& subnet)
106       : address(addr), mask(mask), subnet(subnet) {}
107 };
108
109 struct MaskBoundaryData : MaskData {
110   bool inSubnet;
111   MaskBoundaryData(
112       const std::string& addr,
113       uint8_t mask,
114       const std::string& subnet,
115       bool inSubnet)
116       : MaskData(addr, mask, subnet), inSubnet(inSubnet) {}
117 };
118
119 struct SerializeData {
120   std::string address;
121   ByteVector bytes;
122
123   SerializeData(const std::string& addr, const ByteVector& bytes)
124       : address(addr), bytes(bytes) {}
125 };
126
127 struct IPAddressTest : TestWithParam<AddressData> {
128   void ExpectIsValid(const IPAddress& addr) {
129     AddressData param = GetParam();
130     EXPECT_EQ(param.version, addr.version());
131     EXPECT_EQ(param.address, addr.str());
132     if (param.version == 4) {
133       in_addr v4addr = AddressData::parseAddress4(param.address);
134       EXPECT_EQ(0, memcmp(&v4addr, addr.asV4().toByteArray().data(), 4));
135       EXPECT_TRUE(addr.isV4());
136       EXPECT_FALSE(addr.isV6());
137     } else {
138       in6_addr v6addr = AddressData::parseAddress6(param.address);
139       EXPECT_EQ(0, memcmp(&v6addr, addr.asV6().toByteArray().data(), 16));
140       EXPECT_TRUE(addr.isV6());
141       EXPECT_FALSE(addr.isV4());
142     }
143   }
144 };
145 struct IPAddressFlagTest : TestWithParam<AddressFlags> {};
146 struct IPAddressCtorTest : TestWithParam<std::string> {};
147 struct IPAddressCtorBinaryTest : TestWithParam<ByteVector> {};
148 struct IPAddressMappedTest
149     : TestWithParam<std::pair<std::string, std::string>> {};
150 struct IPAddressMaskTest : TestWithParam<MaskData> {};
151 struct IPAddressMaskBoundaryTest : TestWithParam<MaskBoundaryData> {};
152 struct IPAddressSerializeTest : TestWithParam<SerializeData> {};
153 struct IPAddressByteAccessorTest : TestWithParam<AddressData> {};
154 struct IPAddressBitAccessorTest : TestWithParam<AddressData> {};
155
156 // tests code example
157 TEST(IPAddress, CodeExample) {
158   EXPECT_EQ(4, sizeof(IPAddressV4));
159   EXPECT_EQ(20, sizeof(IPAddressV6));
160   EXPECT_EQ(24, sizeof(IPAddress));
161   IPAddress uninitaddr;
162   IPAddress v4addr("192.0.2.129");
163   IPAddress v6map("::ffff:192.0.2.129");
164   ASSERT_TRUE(uninitaddr.empty());
165   ASSERT_FALSE(v4addr.empty());
166   ASSERT_FALSE(v6map.empty());
167   EXPECT_TRUE(v4addr.inSubnet("192.0.2.0/24"));
168   EXPECT_TRUE(v4addr.inSubnet(IPAddress("192.0.2.0"), 24));
169   EXPECT_TRUE(v4addr.inSubnet("192.0.2.128/30"));
170   EXPECT_FALSE(v4addr.inSubnet("192.0.2.128/32"));
171   EXPECT_EQ(2164392128, v4addr.asV4().toLong());
172   EXPECT_EQ(3221226113, v4addr.asV4().toLongHBO());
173   ASSERT_FALSE(uninitaddr.isV4());
174   ASSERT_FALSE(uninitaddr.isV6());
175   ASSERT_TRUE(v4addr.isV4());
176   ASSERT_TRUE(v6map.isV6());
177   EXPECT_TRUE(v4addr == v6map);
178   ASSERT_TRUE(v6map.isIPv4Mapped());
179   EXPECT_TRUE(v4addr.asV4() == IPAddress::createIPv4(v6map));
180   EXPECT_TRUE(IPAddress::createIPv6(v4addr) == v6map.asV6());
181 }
182
183 TEST(IPAddress, Scope) {
184   // Test that link-local scope is saved
185   auto str = "fe80::62eb:69ff:fe9b:ba60%eth0";
186   IPAddressV6 a2(str);
187   EXPECT_EQ(str, a2.str());
188
189   sockaddr_in6 sock = a2.toSockAddr();
190   EXPECT_NE(0, sock.sin6_scope_id);
191
192   IPAddress a1(str);
193   EXPECT_EQ(str, a1.str());
194
195   a2.setScopeId(0);
196   EXPECT_NE(a1, a2);
197
198   EXPECT_TRUE(a2 < a1);
199 }
200
201 TEST(IPAddress, ScopeNumeric) {
202   // it's very unlikely that the host running these
203   // tests will have 42 network interfaces
204   auto str = "fe80::62eb:69ff:fe9b:ba60%42";
205   IPAddressV6 a2(str);
206   EXPECT_EQ(str, a2.str());
207
208   sockaddr_in6 sock = a2.toSockAddr();
209   EXPECT_NE(0, sock.sin6_scope_id);
210
211   IPAddress a1(str);
212   EXPECT_EQ(str, a1.str());
213
214   a2.setScopeId(0);
215   EXPECT_NE(a1, a2);
216
217   EXPECT_TRUE(a2 < a1);
218 }
219
220 TEST(IPAddress, Ordering) {
221   IPAddress a1("0.1.1.1");
222   IPAddress a2("1.1.1.0");
223   EXPECT_TRUE(a1 < a2);
224
225   IPAddress b1("::ffff:0.1.1.1");
226   IPAddress b2("::ffff:1.1.1.0");
227   EXPECT_TRUE(b1 < b2);
228 }
229
230 TEST(IPAddress, InvalidAddressFamilyExceptions) {
231   // asV4
232   {
233     IPAddress addr;
234     EXPECT_THROW(addr.asV4(), InvalidAddressFamilyException);
235   }
236   // asV6
237   {
238     IPAddress addr;
239     EXPECT_THROW(addr.asV6(), InvalidAddressFamilyException);
240   }
241   // sockaddr ctor
242   {
243     // setup
244     sockaddr_in addr;
245     addr.sin_family = AF_UNSPEC;
246
247     EXPECT_THROW(IPAddress((sockaddr*)&addr), InvalidAddressFamilyException);
248   }
249 }
250
251 TEST(IPAddress, CreateNetwork) {
252   // test valid IPv4 network
253   {
254     auto net = IPAddress::createNetwork("192.168.0.1/24");
255     ASSERT_TRUE(net.first.isV4());
256     EXPECT_EQ("192.168.0.0", net.first.str());
257     EXPECT_EQ(24, net.second);
258     EXPECT_EQ("192.168.0.0/24", IPAddress::networkToString(net));
259   }
260   // test valid IPv4 network without applying mask
261   {
262     auto net = IPAddress::createNetwork("192.168.0.1/24", -1, false);
263     ASSERT_TRUE(net.first.isV4());
264     EXPECT_EQ("192.168.0.1", net.first.str());
265     EXPECT_EQ(24, net.second);
266     EXPECT_EQ("192.168.0.1/24", IPAddress::networkToString(net));
267   }
268   // test valid IPv6 network
269   {
270     auto net = IPAddress::createNetwork("1999::1/24");
271     ASSERT_TRUE(net.first.isV6());
272     EXPECT_EQ("1999::", net.first.str());
273     EXPECT_EQ(24, net.second);
274     EXPECT_EQ("1999::/24", IPAddress::networkToString(net));
275   }
276   // test valid IPv6 network without applying mask
277   {
278     auto net = IPAddress::createNetwork("1999::1/24", -1, false);
279     ASSERT_TRUE(net.first.isV6());
280     EXPECT_EQ("1999::1", net.first.str());
281     EXPECT_EQ(24, net.second);
282     EXPECT_EQ("1999::1/24", IPAddress::networkToString(net));
283   }
284   // test empty string
285   EXPECT_THROW(IPAddress::createNetwork(""), IPAddressFormatException);
286   // test multi slash string
287   EXPECT_THROW(
288       IPAddress::createNetwork("192.168.0.1/24/36"), IPAddressFormatException);
289   // test no slash string with default IPv4
290   {
291     auto net = IPAddress::createNetwork("192.168.0.1");
292     ASSERT_TRUE(net.first.isV4());
293     EXPECT_EQ("192.168.0.1", net.first.str());
294     EXPECT_EQ(32, net.second); // auto-detected
295     net = IPAddress::createNetwork("192.168.0.1", -1, false);
296     ASSERT_TRUE(net.first.isV4());
297     EXPECT_EQ("192.168.0.1", net.first.str());
298     EXPECT_EQ(32, net.second);
299   }
300   // test no slash string with default IPv6
301   {
302     auto net = IPAddress::createNetwork("1999::1");
303     ASSERT_TRUE(net.first.isV6());
304     EXPECT_EQ("1999::1", net.first.str());
305     EXPECT_EQ(128, net.second);
306   }
307   // test no slash string with invalid default
308   EXPECT_THROW(
309       IPAddress::createNetwork("192.168.0.1", 33), IPAddressFormatException);
310 }
311
312 // test assignment operators
313 TEST(IPAddress, Assignment) {
314   static const string kIPv4Addr = "69.63.189.16";
315   static const string kIPv6Addr = "2620:0:1cfe:face:b00c::3";
316
317   // Test assigning IPAddressV6 addr to IPAddress (was V4)
318   {
319     IPAddress addr(kIPv4Addr);
320     IPAddressV6 addrV6 = IPAddress(kIPv6Addr).asV6();
321     EXPECT_TRUE(addr.isV4());
322     EXPECT_EQ(kIPv4Addr, addr.str());
323     addr = addrV6;
324     EXPECT_TRUE(addr.isV6());
325     EXPECT_EQ(kIPv6Addr, addr.str());
326   }
327   // Test assigning IPAddressV4 addr to IPAddress (was V6)
328   {
329     IPAddress addr(kIPv6Addr);
330     IPAddressV4 addrV4 = IPAddress(kIPv4Addr).asV4();
331     EXPECT_TRUE(addr.isV6());
332     EXPECT_EQ(kIPv6Addr, addr.str());
333     addr = addrV4;
334     EXPECT_TRUE(addr.isV4());
335     EXPECT_EQ(kIPv4Addr, addr.str());
336   }
337   // Test assigning IPAddress(v6) to IPAddress (was v4)
338   {
339     IPAddress addr(kIPv4Addr);
340     IPAddress addrV6 = IPAddress(kIPv6Addr);
341     EXPECT_TRUE(addr.isV4());
342     EXPECT_EQ(kIPv4Addr, addr.str());
343     addr = addrV6;
344     EXPECT_TRUE(addr.isV6());
345     EXPECT_EQ(kIPv6Addr, addr.str());
346   }
347   // Test assigning IPAddress(v4) to IPAddress (was v6)
348   {
349     IPAddress addr(kIPv6Addr);
350     IPAddress addrV4 = IPAddress(kIPv4Addr);
351     EXPECT_TRUE(addr.isV6());
352     EXPECT_EQ(kIPv6Addr, addr.str());
353     addr = addrV4;
354     EXPECT_TRUE(addr.isV4());
355     EXPECT_EQ(kIPv4Addr, addr.str());
356   }
357 }
358
359 // Test the default constructors
360 TEST(IPAddress, CtorDefault) {
361   IPAddressV4 v4;
362   EXPECT_EQ(IPAddressV4("0.0.0.0"), v4);
363   IPAddressV6 v6;
364   EXPECT_EQ(IPAddressV6("::0"), v6);
365 }
366
367 TEST(IPAddressV4, validate) {
368   EXPECT_TRUE(IPAddressV4::validate("0.0.0.0"));
369   EXPECT_FALSE(IPAddressV4::validate("0.0.0."));
370   EXPECT_TRUE(IPAddressV4::validate("127.127.127.127"));
371 }
372
373 TEST(IPAddressV6, validate) {
374   EXPECT_TRUE(IPAddressV6::validate("2620:0:1cfe:face:b00c::3"));
375   EXPECT_FALSE(IPAddressV6::validate("0.0.0.0"));
376   EXPECT_TRUE(IPAddressV6::validate("[2620:0:1cfe:face:b00c::3]"));
377   EXPECT_TRUE(IPAddressV6::validate("::ffff:0.1.1.1"));
378   EXPECT_TRUE(IPAddressV6::validate("2620:0000:1cfe:face:b00c:0000:0000:0003"));
379   EXPECT_TRUE(
380       IPAddressV6::validate("2620:0000:1cfe:face:b00c:0000:127.127.127.127"));
381 }
382
383 TEST(IPAddress, validate) {
384   EXPECT_TRUE(IPAddress::validate("0.0.0.0"));
385   EXPECT_TRUE(IPAddress::validate("::"));
386   EXPECT_FALSE(IPAddress::validate("asdf"));
387 }
388
389 // Test addresses constructed using a in[6]_addr value
390 TEST_P(IPAddressTest, CtorAddress) {
391   AddressData param = GetParam();
392   IPAddress strAddr(param.address);
393   IPAddress address;
394
395   if (param.version == 4) {
396     in_addr v4addr = detail::Bytes::mkAddress4(&param.bytes[0]);
397     address = IPAddress(v4addr);
398   } else {
399     in6_addr v6addr = detail::Bytes::mkAddress6(&param.bytes[0]);
400     address = IPAddress(v6addr);
401   }
402   ExpectIsValid(address);
403   EXPECT_EQ(strAddr, address);
404 }
405
406 // Test addresses constructed using a binary address
407 TEST_P(IPAddressTest, CtorBinary) {
408   AddressData param = GetParam();
409   IPAddress address;
410
411   if (param.version == 4) {
412     in_addr v4addr = AddressData::parseAddress4(param.address);
413     address = IPAddress::fromBinary(ByteRange((unsigned char*)&v4addr, 4));
414   } else {
415     in6_addr v6addr = AddressData::parseAddress6(param.address);
416     address = IPAddress::fromBinary(ByteRange((unsigned char*)&v6addr, 16));
417   }
418
419   ExpectIsValid(address);
420   EXPECT_EQ(IPAddress(param.address), address);
421 }
422
423 // Test addresses constructed using a string
424 TEST_P(IPAddressTest, CtorString) {
425   AddressData param = GetParam();
426   IPAddress address(param.address);
427
428   ExpectIsValid(address);
429
430   // Test the direct version-specific constructor
431   if (param.version == 4) {
432     IPAddressV4 v4(param.address);
433     ExpectIsValid(IPAddress(v4));
434     EXPECT_THROW(IPAddressV6 v6(param.address), IPAddressFormatException);
435   } else if (param.version == 6) {
436     IPAddressV6 v6(param.address);
437     ExpectIsValid(IPAddress(v6));
438     EXPECT_THROW(IPAddressV4 v4(param.address), IPAddressFormatException);
439   }
440 }
441
442 TEST(IPAddress, CtorSockaddr) {
443   // test v4 address
444   {
445     // setup
446     sockaddr_in addr;
447     in_addr sin_addr;
448     sin_addr.s_addr = htonl(2122547223);
449     addr.sin_family = AF_INET;
450     addr.sin_addr = sin_addr;
451
452     IPAddress ipAddr((sockaddr*)&addr);
453     EXPECT_TRUE(ipAddr.isV4());
454     EXPECT_EQ("126.131.128.23", ipAddr.str());
455   }
456   // test v6 address
457   {
458     // setup
459     sockaddr_in6 addr;
460     memset(&addr, 0, sizeof(addr));
461     in6_addr sin_addr;
462     // 2620:0:1cfe:face:b00c::3
463     ByteArray16 sec{
464         {38, 32, 0, 0, 28, 254, 250, 206, 176, 12, 0, 0, 0, 0, 0, 3}};
465     std::memcpy(sin_addr.s6_addr, sec.data(), 16);
466     addr.sin6_family = AF_INET6;
467     addr.sin6_addr = sin_addr;
468
469     IPAddress ipAddr((sockaddr*)&addr);
470     EXPECT_TRUE(ipAddr.isV6());
471     EXPECT_EQ("2620:0:1cfe:face:b00c::3", ipAddr.str());
472   }
473   // test nullptr exception
474   {
475     sockaddr* addr = nullptr;
476     EXPECT_THROW(IPAddress((const sockaddr*)addr), IPAddressFormatException);
477   }
478   // test invalid family exception
479   {
480     // setup
481     sockaddr_in addr;
482     in_addr sin_addr;
483     sin_addr.s_addr = htonl(2122547223);
484     addr.sin_family = AF_UNSPEC;
485     addr.sin_addr = sin_addr;
486
487     EXPECT_THROW(IPAddress((sockaddr*)&addr), IPAddressFormatException);
488   }
489 }
490
491 TEST(IPAddress, ToSockaddrStorage) {
492   // test v4 address
493   {
494     string strAddr("126.131.128.23");
495     IPAddress addr(strAddr);
496     sockaddr_storage out;
497
498     ASSERT_TRUE(addr.isV4()); // test invariant
499     EXPECT_GT(addr.toSockaddrStorage(&out), 0);
500
501     IPAddress sockAddr((sockaddr*)&out);
502     ASSERT_TRUE(sockAddr.isV4());
503     EXPECT_EQ(strAddr, sockAddr.str());
504   }
505   // test v6 address
506   {
507     string strAddr("2620:0:1cfe:face:b00c::3");
508     IPAddress addr(strAddr);
509     sockaddr_storage out;
510
511     ASSERT_TRUE(addr.isV6()); // test invariant
512     EXPECT_GT(addr.toSockaddrStorage(&out), 0);
513
514     IPAddress sockAddr((sockaddr*)&out);
515     ASSERT_TRUE(sockAddr.isV6());
516     EXPECT_EQ(strAddr, sockAddr.str());
517   }
518   // test nullptr exception
519   {
520     sockaddr_storage* out = nullptr;
521     IPAddress addr("127.0.0.1");
522     EXPECT_THROW(addr.toSockaddrStorage(out), IPAddressFormatException);
523   }
524   // test invalid family exception
525   {
526     IPAddress addr;
527     sockaddr_storage out;
528     ASSERT_EQ(AF_UNSPEC, addr.family());
529     EXPECT_THROW(addr.toSockaddrStorage(&out), InvalidAddressFamilyException);
530   }
531 }
532
533 TEST(IPAddress, ToString) {
534   // Test with IPAddressV4
535   IPAddressV4 addr_10_0_0_1("10.0.0.1");
536   EXPECT_EQ("10.0.0.1", folly::to<string>(addr_10_0_0_1));
537   // Test with IPAddressV6
538   IPAddressV6 addr_1("::1");
539   EXPECT_EQ("::1", folly::to<string>(addr_1));
540   // Test with IPAddress, both V4 and V6
541   IPAddress addr_10_1_2_3("10.1.2.3");
542   EXPECT_EQ("10.1.2.3", folly::to<string>(addr_10_1_2_3));
543   IPAddress addr_1_2_3("1:2::3");
544   EXPECT_EQ("1:2::3", folly::to<string>(addr_1_2_3));
545
546   // Test a combination of all the above arguments
547   EXPECT_EQ(
548       "1:2::3 - 10.0.0.1 - ::1 - 10.1.2.3",
549       folly::to<string>(
550           addr_1_2_3,
551           " - ",
552           addr_10_0_0_1,
553           " - ",
554           addr_1,
555           " - ",
556           addr_10_1_2_3));
557 }
558
559 TEST(IPaddress, toInverseArpaName) {
560   IPAddressV4 addr_ipv4("10.0.0.1");
561   EXPECT_EQ("1.0.0.10.in-addr.arpa", addr_ipv4.toInverseArpaName());
562   IPAddressV6 addr_ipv6("2620:0000:1cfe:face:b00c:0000:0000:0003");
563   EXPECT_EQ(
564       sformat(
565           "{}.ip6.arpa",
566           "3.0.0.0.0.0.0.0.0.0.0.0.c.0.0.b.e.c.a.f.e.f.c.1.0.0.0.0.0.2.6.2"),
567       addr_ipv6.toInverseArpaName());
568 }
569
570 TEST(IPaddress, fromInverseArpaName) {
571   EXPECT_EQ(
572       IPAddressV4("10.0.0.1"),
573       IPAddressV4::fromInverseArpaName("1.0.0.10.in-addr.arpa"));
574   EXPECT_EQ(
575       IPAddressV6("2620:0000:1cfe:face:b00c:0000:0000:0003"),
576       IPAddressV6::fromInverseArpaName(sformat(
577           "{}.ip6.arpa",
578           "3.0.0.0.0.0.0.0.0.0.0.0.c.0.0.b.e.c.a.f.e.f.c.1.0.0.0.0.0.2.6.2")));
579 }
580
581 // Test that invalid string values are killed
582 TEST_P(IPAddressCtorTest, InvalidCreation) {
583   string addr = GetParam();
584   EXPECT_THROW(IPAddress((const string)addr), IPAddressFormatException)
585       << "IPAddress(" << addr << ") "
586       << "should have thrown an IPAddressFormatException";
587 }
588
589 // Test that invalid binary values throw an exception
590 TEST_P(IPAddressCtorBinaryTest, InvalidBinary) {
591   auto bin = GetParam();
592   EXPECT_THROW(
593       IPAddress::fromBinary(ByteRange(&bin[0], bin.size())),
594       IPAddressFormatException);
595 }
596
597 TEST(IPAddressSource, ToHex) {
598   vector<std::uint8_t> data = {{0xff, 0x20, 0x45}};
599   EXPECT_EQ(detail::Bytes::toHex(data.data(), 0), "");
600   EXPECT_EQ(detail::Bytes::toHex(data.data(), 1), "ff");
601   EXPECT_EQ(detail::Bytes::toHex(data.data(), 2), "ff20");
602   EXPECT_EQ(detail::Bytes::toHex(data.data(), 3), "ff2045");
603 }
604
605 // Test toFullyQualified()
606 TEST(IPAddress, ToFullyQualifiedFb) {
607   IPAddress ip("2620:0:1cfe:face:b00c::3");
608   EXPECT_EQ("2620:0000:1cfe:face:b00c:0000:0000:0003", ip.toFullyQualified())
609       << ip;
610 }
611 TEST(IPAddress, ToFullyQualifiedLocal) {
612   IPAddress ip("::1");
613   EXPECT_EQ("0000:0000:0000:0000:0000:0000:0000:0001", ip.toFullyQualified())
614       << ip;
615 }
616 TEST(IPAddress, ToFullyQualifiedAppendV6) {
617   IPAddress ip("2620:0:1cfe:face:b00c::3");
618   std::string result;
619   ip.toFullyQualifiedAppend(result);
620   EXPECT_EQ("2620:0000:1cfe:face:b00c:0000:0000:0003", result) << ip;
621 }
622 TEST(IPAddress, ToFullyQualifiedAppendV4) {
623   IPAddress ip("127.0.0.1");
624   std::string result;
625   ip.toFullyQualifiedAppend(result);
626   EXPECT_EQ("127.0.0.1", result) << ip;
627 }
628 TEST(IPAddress, ToFullyQualifiedSizeV6) {
629   auto actual = IPAddressV6::kToFullyQualifiedSize;
630   auto expected = IPAddress("::").toFullyQualified().size();
631   EXPECT_EQ(expected, actual);
632 }
633 TEST(IPAddress, MaxToFullyQualifiedSizeV4) {
634   auto actual = IPAddressV4::kMaxToFullyQualifiedSize;
635   auto expected = IPAddress("255.255.255.255").toFullyQualified().size();
636   EXPECT_EQ(expected, actual);
637 }
638
639 // test v4-v6 mapped addresses
640 TEST_P(IPAddressMappedTest, MappedEqual) {
641   auto param = GetParam();
642   string mappedIp = param.first;
643   string otherIp = param.second;
644
645   auto mapped = IPAddress(mappedIp);
646   auto expected = IPAddress(otherIp);
647
648   EXPECT_EQ(expected, mapped);
649
650   IPAddress v6addr;
651   if (mapped.isV4()) {
652     v6addr = mapped.asV4().createIPv6();
653   } else if (expected.isV4()) {
654     v6addr = expected.asV4().createIPv6();
655   }
656   EXPECT_TRUE(v6addr.isV6());
657   EXPECT_TRUE(mapped == v6addr);
658   EXPECT_TRUE(expected == v6addr);
659 }
660
661 // Test subnet mask calculations
662 TEST_P(IPAddressMaskTest, Masks) {
663   auto param = GetParam();
664
665   IPAddress ip(param.address);
666   IPAddress masked = ip.mask(param.mask);
667   EXPECT_EQ(param.subnet, masked.str())
668       << param.address << "/" << folly::to<std::string>(param.mask) << " -> "
669       << param.subnet;
670 }
671
672 // Test inSubnet calculations
673 TEST_P(IPAddressMaskTest, InSubnet) {
674   auto param = GetParam();
675
676   IPAddress ip(param.address);
677   IPAddress subnet(param.subnet);
678   EXPECT_TRUE(ip.inSubnet(subnet, param.mask));
679 }
680
681 // Test boundary conditions for subnet calculations
682 TEST_P(IPAddressMaskBoundaryTest, NonMaskedSubnet) {
683   auto param = GetParam();
684   IPAddress ip(param.address);
685   IPAddress subnet(param.subnet);
686   EXPECT_EQ(param.inSubnet, ip.inSubnet(subnet, param.mask));
687 }
688
689 TEST(IPAddress, UnitializedEqual) {
690   IPAddress addrEmpty;
691   IPAddress ip4("127.0.0.1");
692   EXPECT_FALSE(addrEmpty == ip4);
693   EXPECT_FALSE(ip4 == addrEmpty);
694   IPAddress ip6("::1");
695   EXPECT_FALSE(addrEmpty == ip6);
696   EXPECT_FALSE(ip6 == addrEmpty);
697   IPAddress ip6Map("::ffff:192.0.2.129");
698   EXPECT_FALSE(addrEmpty == ip6Map);
699   EXPECT_FALSE(ip6Map == addrEmpty);
700   IPAddress ip4Zero("0.0.0.0");
701   EXPECT_FALSE(addrEmpty == ip4Zero);
702   EXPECT_FALSE(ip4Zero == addrEmpty);
703   IPAddress ip6Zero("::");
704   EXPECT_FALSE(addrEmpty == ip6Zero);
705   EXPECT_FALSE(ip6Zero == addrEmpty);
706   EXPECT_EQ(addrEmpty, addrEmpty);
707 }
708
709 // Test subnet calcs with 6to4 addresses
710 TEST(IPAddress, InSubnetWith6to4) {
711   auto ip = IPAddress("2002:c000:022a::"); // 192.0.2.42
712   auto subnet = IPAddress("192.0.0.0");
713   EXPECT_TRUE(ip.inSubnet(subnet, 16));
714
715   auto ip2 = IPAddress("192.0.0.1");
716   auto subnet2 = IPAddress("2002:c000:0000::"); // 192.0.0.0
717   EXPECT_TRUE(ip2.inSubnet(subnet2, 14));
718
719   auto ip3 = IPAddress("2002:c000:022a::"); // 192.0.2.42
720   auto subnet3 = IPAddress("2002:c000:0000::"); // 192.0.0.0
721   EXPECT_TRUE(ip3.inSubnet(subnet3, 16));
722 }
723
724 static const vector<string> ipv4Strs = {
725     "127.0.0.1",
726     "198.168.0.1",
727     "8.8.0.0",
728 };
729 TEST(IPAddress, getIPv6For6To4) {
730   for (auto ipv4Str : ipv4Strs) {
731     auto ip = IPAddress(ipv4Str);
732     EXPECT_TRUE(ip.isV4());
733     IPAddressV4 ipv4 = ip.asV4();
734     auto ipv6 = ipv4.getIPv6For6To4();
735     EXPECT_EQ(ipv6.type(), IPAddressV6::Type::T6TO4);
736     auto ipv4New = ipv6.getIPv4For6To4();
737     EXPECT_TRUE(ipv4Str.compare(ipv4New.str()) == 0);
738   }
739 }
740
741 static const vector<pair<string, uint8_t>> invalidMasks = {
742     {"127.0.0.1", 33},
743     {"::1", 129},
744 };
745 TEST(IPAddress, InvalidMask) {
746   for (auto& tc : invalidMasks) {
747     auto ip = IPAddress(tc.first);
748     EXPECT_THROW(ip.mask(tc.second), IPAddressFormatException);
749   }
750 }
751
752 static const vector<pair<string, IPAddressV6::Type>> v6types = {
753     {"::1", IPAddressV6::Type::NORMAL},
754     {"2620:0:1cfe:face:b00c::3", IPAddressV6::Type::NORMAL},
755     {"2001:0000:4136:e378:8000:63bf:3fff:fdd2", IPAddressV6::Type::TEREDO},
756     {"2002:c000:022a::", IPAddressV6::Type::T6TO4},
757 };
758 TEST(IPAddress, V6Types) {
759   auto mkName = [&](const IPAddressV6::Type t) -> string {
760     switch (t) {
761       case IPAddressV6::Type::TEREDO:
762         return "teredo";
763       case IPAddressV6::Type::T6TO4:
764         return "6to4";
765       default:
766         return "default";
767     }
768   };
769
770   for (auto& tc : v6types) {
771     auto ip = IPAddress(tc.first);
772     EXPECT_TRUE(ip.isV6());
773     IPAddressV6 ipv6 = ip.asV6();
774     EXPECT_EQ(tc.second, ipv6.type())
775         << "expected " << mkName(tc.second) << ", got " << mkName(ipv6.type());
776     switch (tc.second) {
777       case IPAddressV6::Type::TEREDO:
778         EXPECT_TRUE(ipv6.isTeredo()) << "isTeredo was false";
779         EXPECT_FALSE(ipv6.is6To4()) << "is6To4 was true";
780         break;
781       case IPAddressV6::Type::T6TO4:
782         EXPECT_TRUE(ipv6.is6To4()) << "is6To4 was false";
783         EXPECT_FALSE(ipv6.isTeredo()) << "isTeredo was true";
784         break;
785       case IPAddressV6::Type::NORMAL:
786         EXPECT_FALSE(ipv6.is6To4()) << "is6To4 was true";
787         EXPECT_FALSE(ipv6.isTeredo()) << "isTeredo was true";
788         break;
789       default:
790         FAIL() << "Invalid expected type: " << to<std::string>(tc.second);
791     }
792   }
793 }
794
795 static const vector<pair<string, uint32_t>> provideToLong = {
796     {"0.0.0.0", 0},
797     {"10.0.0.0", 167772160},
798     {"126.131.128.23", 2122547223},
799     {"192.168.0.0", 3232235520},
800 };
801 TEST(IPAddress, ToLong) {
802   for (auto& tc : provideToLong) {
803     auto ip = IPAddress(tc.first);
804     EXPECT_TRUE(ip.isV4());
805     IPAddressV4 ipv4 = ip.asV4();
806     EXPECT_EQ(tc.second, ipv4.toLongHBO());
807
808     auto ip2 = IPAddress::fromLongHBO(tc.second);
809     EXPECT_TRUE(ip2.isV4());
810     EXPECT_TRUE(tc.first.compare(ip2.str()) == 0);
811     EXPECT_EQ(tc.second, ip2.asV4().toLongHBO());
812
813     auto nla = htonl(tc.second);
814     auto ip3 = IPAddress::fromLong(nla);
815     EXPECT_TRUE(ip3.isV4());
816     EXPECT_TRUE(tc.first.compare(ip3.str()) == 0);
817     EXPECT_EQ(nla, ip3.asV4().toLong());
818   }
819 }
820
821 TEST(IPAddress, fromBinaryV4) {
822   for (auto& tc : provideToLong) {
823     SCOPED_TRACE(tc.first);
824     union {
825       uint8_t u8[4];
826       uint32_t u32;
827     } data;
828     data.u32 = Endian::big(tc.second);
829     ByteRange bytes(data.u8, 4);
830
831     auto fromBin = IPAddressV4::fromBinary(bytes);
832     IPAddressV4 fromStr(tc.first);
833     EXPECT_EQ(fromStr, fromBin);
834
835     IPAddressV4 addr2("0.0.0.0");
836     addr2 = IPAddressV4::fromBinary(bytes);
837     EXPECT_EQ(fromStr, addr2);
838
839     IPAddress genericAddr = IPAddress::fromBinary(bytes);
840     ASSERT_TRUE(genericAddr.isV4());
841     EXPECT_EQ(fromStr, genericAddr.asV4());
842     EXPECT_EQ(ByteRange(genericAddr.bytes(), genericAddr.byteCount()), bytes);
843   }
844
845   uint8_t data[20];
846   EXPECT_THROW(
847       IPAddressV4::fromBinary(ByteRange(data, 3)), IPAddressFormatException);
848   EXPECT_THROW(
849       IPAddressV4::fromBinary(ByteRange(data, 16)), IPAddressFormatException);
850   EXPECT_THROW(
851       IPAddressV4::fromBinary(ByteRange(data, 20)), IPAddressFormatException);
852 }
853
854 TEST(IPAddress, toBinaryV4) {
855   for (auto& tc : provideToLong) {
856     SCOPED_TRACE(tc.first);
857     union {
858       uint8_t u8[4];
859       uint32_t u32;
860     } data;
861     data.u32 = Endian::big(tc.second);
862     ByteRange bytes(data.u8, 4);
863
864     auto fromBin = IPAddressV4::fromBinary(bytes);
865     auto toBin = fromBin.toBinary();
866     EXPECT_EQ(bytes, toBin);
867   }
868 }
869
870 using ByteArray8 = std::array<uint8_t, 8>;
871
872 static auto join8 = [](std::array<ByteArray8, 2> parts) {
873   ByteArray16 _return;
874   std::memcpy(_return.data(), parts.data(), _return.size());
875   return _return;
876 };
877
878 static const vector<pair<string, ByteArray16>> provideBinary16Bytes = {
879     make_pair(
880         "::0",
881         join8({{
882             ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
883             ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
884         }})),
885     make_pair(
886         "1::2",
887         join8({{
888             ByteArray8{{0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
889             ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x02}},
890         }})),
891     make_pair(
892         "fe80::0012:34ff:fe56:78ab",
893         join8(
894             {{ByteArray8{{0xfe, 0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
895               ByteArray8{{0x00, 0x12, 0x34, 0xff, 0xfe, 0x56, 0x78, 0xab}}}})),
896     make_pair(
897         "2001:db8:1234:5678:90ab:cdef:8765:4321",
898         join8({{
899             ByteArray8{{0x20, 0x01, 0x0d, 0xb8, 0x12, 0x34, 0x56, 0x78}},
900             ByteArray8{{0x90, 0xab, 0xcd, 0xef, 0x87, 0x65, 0x43, 0x21}},
901         }})),
902     make_pair(
903         "::ffff:0:c0a8:1",
904         join8({{
905             ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
906             ByteArray8{{0xff, 0xff, 0x00, 0x00, 0xc0, 0xa8, 0x00, 0x01}},
907         }})),
908 };
909
910 TEST(IPAddress, fromBinaryV6) {
911   for (auto& tc : provideBinary16Bytes) {
912     SCOPED_TRACE(tc.first);
913     ByteRange bytes(&tc.second.front(), tc.second.size());
914
915     auto fromBin = IPAddressV6::fromBinary(bytes);
916     IPAddressV6 fromStr(tc.first);
917     EXPECT_EQ(fromStr, fromBin);
918
919     IPAddressV6 addr2("::0");
920     addr2 = IPAddressV6::fromBinary(bytes);
921     EXPECT_EQ(fromStr, addr2);
922
923     IPAddress genericAddr = IPAddress::fromBinary(bytes);
924     ASSERT_TRUE(genericAddr.isV6());
925     EXPECT_EQ(fromStr, genericAddr.asV6());
926     EXPECT_EQ(ByteRange(genericAddr.bytes(), genericAddr.byteCount()), bytes);
927   }
928
929   uint8_t data[20];
930   EXPECT_THROW(
931       IPAddressV6::fromBinary(ByteRange(data, 3)), IPAddressFormatException);
932   EXPECT_THROW(
933       IPAddressV6::fromBinary(ByteRange(data, 4)), IPAddressFormatException);
934   EXPECT_THROW(
935       IPAddressV6::fromBinary(ByteRange(data, 20)), IPAddressFormatException);
936 }
937
938 TEST(IPAddress, toBinaryV6) {
939   for (auto& tc : provideBinary16Bytes) {
940     SCOPED_TRACE(tc.first);
941     ByteRange bytes(&tc.second.front(), tc.second.size());
942
943     auto fromBin = IPAddressV6::fromBinary(bytes);
944     auto toBin = fromBin.toBinary();
945     EXPECT_EQ(bytes, toBin);
946   }
947 }
948
949 TEST_P(IPAddressFlagTest, IsLoopback) {
950   AddressFlags param = GetParam();
951   IPAddress addr(param.address);
952
953   EXPECT_EQ(param.version, addr.version());
954   EXPECT_EQ(param.isLoopback(), addr.isLoopback());
955 }
956
957 TEST_P(IPAddressFlagTest, IsPrivate) {
958   AddressFlags param = GetParam();
959   IPAddress addr(param.address);
960
961   EXPECT_EQ(param.version, addr.version());
962   EXPECT_EQ(param.isPrivate(), addr.isPrivate()) << addr;
963 }
964
965 TEST_P(IPAddressFlagTest, IsNonroutable) {
966   AddressFlags param = GetParam();
967   IPAddress addr(param.address);
968
969   EXPECT_EQ(param.version, addr.version());
970   EXPECT_EQ(param.isNonroutable(), addr.isNonroutable()) << addr;
971 }
972
973 TEST_P(IPAddressFlagTest, IsZero) {
974   AddressFlags param = GetParam();
975   IPAddress addr(param.address);
976
977   EXPECT_EQ(param.version, addr.version());
978   EXPECT_EQ(param.isZero(), addr.isZero()) << addr;
979 }
980
981 TEST_P(IPAddressFlagTest, IsLinkLocal) {
982   AddressFlags param = GetParam();
983   IPAddress addr(param.address);
984   EXPECT_EQ(param.isLinkLocal(), addr.isLinkLocal()) << addr;
985 }
986
987 TEST(IPAddress, CreateLinkLocal) {
988   IPAddressV6 addr(IPAddressV6::LINK_LOCAL, MacAddress("00:05:73:f9:46:fc"));
989   EXPECT_EQ(IPAddressV6("fe80::0205:73ff:fef9:46fc"), addr);
990
991   addr = IPAddressV6(IPAddressV6::LINK_LOCAL, MacAddress("02:00:00:12:34:56"));
992   EXPECT_EQ(IPAddressV6("fe80::ff:fe12:3456"), addr);
993 }
994
995 TEST_P(IPAddressFlagTest, IsLinkLocalBroadcast) {
996   AddressFlags param = GetParam();
997   IPAddress addr(param.address);
998   EXPECT_EQ(param.version, addr.version());
999   EXPECT_EQ(param.isLinkLocalBroadcast(), addr.isLinkLocalBroadcast());
1000 }
1001
1002 TEST(IPAddress, SolicitedNodeAddress) {
1003   // An example from RFC 4291 section 2.7.1
1004   EXPECT_EQ(
1005       IPAddressV6("ff02::1:ff0e:8c6c"),
1006       IPAddressV6("4037::01:800:200e:8c6c").getSolicitedNodeAddress());
1007
1008   // An example from wikipedia
1009   // (http://en.wikipedia.org/wiki/Solicited-node_multicast_address)
1010   EXPECT_EQ(
1011       IPAddressV6("ff02::1:ff28:9c5a"),
1012       IPAddressV6("fe80::2aa:ff:fe28:9c5a").getSolicitedNodeAddress());
1013 }
1014
1015 TEST_P(IPAddressByteAccessorTest, CheckBytes) {
1016   auto addrData = GetParam();
1017   IPAddress ip(addrData.address);
1018   size_t i = 0;
1019   for (auto byitr = addrData.bytes.begin(); i < ip.byteCount(); ++i, ++byitr) {
1020     EXPECT_EQ(*byitr, ip.getNthMSByte(i));
1021     EXPECT_EQ(
1022         *byitr,
1023         ip.isV4() ? ip.asV4().getNthMSByte(i) : ip.asV6().getNthMSByte(i));
1024   }
1025   i = 0;
1026   for (auto byritr = addrData.bytes.rbegin(); i < ip.byteCount();
1027        ++i, ++byritr) {
1028     EXPECT_EQ(*byritr, ip.getNthLSByte(i));
1029     EXPECT_EQ(
1030         *byritr,
1031         ip.isV4() ? ip.asV4().getNthLSByte(i) : ip.asV6().getNthLSByte(i));
1032   }
1033 }
1034
1035 TEST_P(IPAddressBitAccessorTest, CheckBits) {
1036   auto addrData = GetParam();
1037   auto littleEndianAddrData = addrData.bytes;
1038   // IPAddress stores address data in n/w byte order.
1039   reverse(littleEndianAddrData.begin(), littleEndianAddrData.end());
1040   // Bit iterator goes from LSBit to MSBit
1041   // We will traverse the IPAddress bits from 0 to bitCount -1
1042   auto bitr = folly::makeBitIterator(littleEndianAddrData.begin());
1043   IPAddress ip(addrData.address);
1044   for (size_t i = 0; i < ip.bitCount(); ++i) {
1045     auto msbIndex = ip.bitCount() - i - 1;
1046     EXPECT_EQ(*bitr, ip.getNthMSBit(msbIndex));
1047     EXPECT_EQ(
1048         *bitr,
1049         ip.isV4() ? ip.asV4().getNthMSBit(msbIndex)
1050                   : ip.asV6().getNthMSBit(msbIndex));
1051     EXPECT_EQ(*bitr, ip.getNthLSBit(i));
1052     EXPECT_EQ(
1053         *bitr, ip.isV4() ? ip.asV4().getNthLSBit(i) : ip.asV6().getNthLSBit(i));
1054     ++bitr;
1055   }
1056 }
1057
1058 TEST(IPAddress, InvalidByteAccess) {
1059   IPAddress ip4("10.10.10.10");
1060   // MSByte, LSByte accessors are 0 indexed
1061   EXPECT_THROW(ip4.getNthMSByte(ip4.byteCount()), std::invalid_argument);
1062   EXPECT_THROW(ip4.getNthLSByte(ip4.byteCount()), std::invalid_argument);
1063   EXPECT_THROW(ip4.getNthMSByte(-1), std::invalid_argument);
1064   EXPECT_THROW(ip4.getNthLSByte(-1), std::invalid_argument);
1065   auto asV4 = ip4.asV4();
1066   EXPECT_THROW(asV4.getNthMSByte(asV4.byteCount()), std::invalid_argument);
1067   EXPECT_THROW(asV4.getNthLSByte(asV4.byteCount()), std::invalid_argument);
1068   EXPECT_THROW(asV4.getNthMSByte(-1), std::invalid_argument);
1069   EXPECT_THROW(asV4.getNthLSByte(-1), std::invalid_argument);
1070
1071   IPAddress ip6("2620:0:1cfe:face:b00c::3");
1072   EXPECT_THROW(ip6.getNthMSByte(ip6.byteCount()), std::invalid_argument);
1073   EXPECT_THROW(ip6.getNthLSByte(ip6.byteCount()), std::invalid_argument);
1074   EXPECT_THROW(ip6.getNthMSByte(-1), std::invalid_argument);
1075   EXPECT_THROW(ip6.getNthLSByte(-1), std::invalid_argument);
1076   auto asV6 = ip6.asV6();
1077   EXPECT_THROW(asV6.getNthMSByte(asV6.byteCount()), std::invalid_argument);
1078   EXPECT_THROW(asV6.getNthLSByte(asV6.byteCount()), std::invalid_argument);
1079   EXPECT_THROW(asV6.getNthMSByte(-1), std::invalid_argument);
1080   EXPECT_THROW(asV6.getNthLSByte(-1), std::invalid_argument);
1081 }
1082
1083 TEST(IPAddress, InvalidBBitAccess) {
1084   IPAddress ip4("10.10.10.10");
1085   // MSByte, LSByte accessors are 0 indexed
1086   EXPECT_THROW(ip4.getNthMSBit(ip4.bitCount()), std::invalid_argument);
1087   EXPECT_THROW(ip4.getNthLSBit(ip4.bitCount()), std::invalid_argument);
1088   EXPECT_THROW(ip4.getNthMSBit(-1), std::invalid_argument);
1089   EXPECT_THROW(ip4.getNthLSBit(-1), std::invalid_argument);
1090   auto asV4 = ip4.asV4();
1091   EXPECT_THROW(asV4.getNthMSBit(asV4.bitCount()), std::invalid_argument);
1092   EXPECT_THROW(asV4.getNthLSBit(asV4.bitCount()), std::invalid_argument);
1093   EXPECT_THROW(asV4.getNthMSBit(-1), std::invalid_argument);
1094   EXPECT_THROW(asV4.getNthLSBit(-1), std::invalid_argument);
1095
1096   IPAddress ip6("2620:0:1cfe:face:b00c::3");
1097   EXPECT_THROW(ip6.getNthMSBit(ip6.bitCount()), std::invalid_argument);
1098   EXPECT_THROW(ip6.getNthLSBit(ip6.bitCount()), std::invalid_argument);
1099   EXPECT_THROW(ip6.getNthMSBit(-1), std::invalid_argument);
1100   EXPECT_THROW(ip6.getNthLSBit(-1), std::invalid_argument);
1101   auto asV6 = ip6.asV6();
1102   EXPECT_THROW(asV6.getNthMSBit(asV6.bitCount()), std::invalid_argument);
1103   EXPECT_THROW(asV6.getNthLSBit(asV6.bitCount()), std::invalid_argument);
1104   EXPECT_THROW(asV6.getNthMSBit(-1), std::invalid_argument);
1105   EXPECT_THROW(asV6.getNthLSBit(-1), std::invalid_argument);
1106 }
1107
1108 TEST(IPAddress, StringFormat) {
1109   in6_addr a6;
1110   for (int i = 0; i < 8; ++i) {
1111     auto t = htons(0x0123 + ((i % 4) * 0x4444));
1112 #ifdef _WIN32
1113     a6.u.Word[i] = t;
1114 #else
1115     a6.s6_addr16[i] = t;
1116 #endif
1117   }
1118   EXPECT_EQ(
1119       "0123:4567:89ab:cdef:0123:4567:89ab:cdef", detail::fastIpv6ToString(a6));
1120
1121   in_addr a4;
1122   a4.s_addr = htonl(0x01020304);
1123   EXPECT_EQ("1.2.3.4", detail::fastIpv4ToString(a4));
1124 }
1125
1126 TEST(IPAddress, getMacAddressFromLinkLocal) {
1127   IPAddressV6 ip6("fe80::f652:14ff:fec5:74d8");
1128   EXPECT_TRUE(ip6.getMacAddressFromLinkLocal().hasValue());
1129   EXPECT_EQ("f4:52:14:c5:74:d8", ip6.getMacAddressFromLinkLocal()->toString());
1130 }
1131
1132 TEST(IPAddress, getMacAddressFromLinkLocal_Negative) {
1133   IPAddressV6 no_link_local_ip6("2803:6082:a2:4447::1");
1134   EXPECT_FALSE(no_link_local_ip6.getMacAddressFromLinkLocal().hasValue());
1135   no_link_local_ip6 = IPAddressV6("fe80::f652:14ff:ccc5:74d8");
1136   EXPECT_FALSE(no_link_local_ip6.getMacAddressFromLinkLocal().hasValue());
1137   no_link_local_ip6 = IPAddressV6("fe80::f652:14ff:ffc5:74d8");
1138   EXPECT_FALSE(no_link_local_ip6.getMacAddressFromLinkLocal().hasValue());
1139   no_link_local_ip6 = IPAddressV6("fe81::f652:14ff:ffc5:74d8");
1140   EXPECT_FALSE(no_link_local_ip6.getMacAddressFromLinkLocal().hasValue());
1141 }
1142
1143 TEST(IPAddress, getMacAddressFromEUI64) {
1144   IPAddressV6 ip6("2401:db00:3020:51dc:4a57:ddff:fe04:5643");
1145   EXPECT_TRUE(ip6.getMacAddressFromEUI64().hasValue());
1146   EXPECT_EQ("48:57:dd:04:56:43", ip6.getMacAddressFromEUI64()->toString());
1147   ip6 = IPAddressV6("fe80::4a57:ddff:fe04:5643");
1148   EXPECT_TRUE(ip6.getMacAddressFromEUI64().hasValue());
1149   EXPECT_EQ("48:57:dd:04:56:43", ip6.getMacAddressFromEUI64()->toString());
1150 }
1151
1152 TEST(IPAddress, getMacAddressFromEUI64_Negative) {
1153   IPAddressV6 not_eui64_ip6("2401:db00:3020:51dc:face:0000:009a:0000");
1154   EXPECT_FALSE(not_eui64_ip6.getMacAddressFromEUI64().hasValue());
1155 }
1156
1157 TEST(IPAddress, LongestCommonPrefix) {
1158   IPAddress ip10("10.0.0.0");
1159   IPAddress ip11("11.0.0.0");
1160   IPAddress ip12("12.0.0.0");
1161   IPAddress ip128("128.0.0.0");
1162   IPAddress ip10dot10("10.10.0.0");
1163   auto prefix = IPAddress::longestCommonPrefix({ip10, 8}, {ip128, 8});
1164   auto prefix4 =
1165       IPAddressV4::longestCommonPrefix({ip10.asV4(), 8}, {ip128.asV4(), 8});
1166   // No bits match b/w 128/8 and 10/8
1167   EXPECT_EQ(IPAddress("0.0.0.0"), prefix.first);
1168   EXPECT_EQ(0, prefix.second);
1169   EXPECT_EQ(IPAddressV4("0.0.0.0"), prefix4.first);
1170   EXPECT_EQ(0, prefix4.second);
1171
1172   prefix = IPAddress::longestCommonPrefix({ip10, 8}, {ip10dot10, 16});
1173   prefix4 = IPAddressV4::longestCommonPrefix(
1174       {ip10.asV4(), 8}, {ip10dot10.asV4(), 16});
1175   // Between 10/8 and 10.10/16, 10/8 is the longest common match
1176   EXPECT_EQ(ip10, prefix.first);
1177   EXPECT_EQ(8, prefix.second);
1178   EXPECT_EQ(ip10.asV4(), prefix4.first);
1179   EXPECT_EQ(8, prefix4.second);
1180
1181   prefix = IPAddress::longestCommonPrefix({ip11, 8}, {ip12, 8});
1182   prefix4 =
1183       IPAddressV4::longestCommonPrefix({ip11.asV4(), 8}, {ip12.asV4(), 8});
1184   // 12 = 1100, 11 = 1011, longest match - 1000 = 8
1185   EXPECT_EQ(IPAddress("8.0.0.0"), prefix.first);
1186   EXPECT_EQ(5, prefix.second);
1187   EXPECT_EQ(IPAddressV4("8.0.0.0"), prefix4.first);
1188   EXPECT_EQ(5, prefix4.second);
1189
1190   // Between 128/1 and 128/2, longest match 128/1
1191   prefix = IPAddress::longestCommonPrefix({ip128, 1}, {ip128, 2});
1192   prefix4 =
1193       IPAddressV4::longestCommonPrefix({ip128.asV4(), 1}, {ip128.asV4(), 2});
1194   EXPECT_EQ(ip128, prefix.first);
1195   EXPECT_EQ(1, prefix.second);
1196   EXPECT_EQ(ip128.asV4(), prefix4.first);
1197   EXPECT_EQ(1, prefix4.second);
1198
1199   IPAddress ip6("2620:0:1cfe:face:b00c::3");
1200   prefix = IPAddress::longestCommonPrefix(
1201       {ip6, ip6.bitCount()}, {ip6, ip6.bitCount()});
1202   auto prefix6 = IPAddressV6::longestCommonPrefix(
1203       {ip6.asV6(), IPAddressV6::bitCount()},
1204       {ip6.asV6(), IPAddressV6::bitCount()});
1205   // Longest common b/w me and myself is myself
1206   EXPECT_EQ(ip6, prefix.first);
1207   EXPECT_EQ(ip6.bitCount(), prefix.second);
1208   EXPECT_EQ(ip6.asV6(), prefix6.first);
1209   EXPECT_EQ(ip6.asV6().bitCount(), prefix6.second);
1210
1211   IPAddress ip6Zero("::");
1212   prefix = IPAddress::longestCommonPrefix({ip6, ip6.bitCount()}, {ip6Zero, 0});
1213   prefix6 = IPAddressV6::longestCommonPrefix(
1214       {ip6.asV6(), IPAddressV6::bitCount()}, {ip6Zero.asV6(), 0});
1215   // Longest common b/w :: (ipv6 equivalent of 0/0) is ::
1216   EXPECT_EQ(ip6Zero, prefix.first);
1217   EXPECT_EQ(0, prefix.second);
1218
1219   // Exceptional cases
1220   EXPECT_THROW(
1221       IPAddress::longestCommonPrefix({ip10, 8}, {ip6, 128}),
1222       std::invalid_argument);
1223   EXPECT_THROW(
1224       IPAddress::longestCommonPrefix({ip10, ip10.bitCount() + 1}, {ip10, 8}),
1225       std::invalid_argument);
1226   EXPECT_THROW(
1227       IPAddressV4::longestCommonPrefix(
1228           {ip10.asV4(), IPAddressV4::bitCount() + 1}, {ip10.asV4(), 8}),
1229       std::invalid_argument);
1230   EXPECT_THROW(
1231       IPAddress::longestCommonPrefix(
1232           {ip6, ip6.bitCount() + 1}, {ip6, ip6.bitCount()}),
1233       std::invalid_argument);
1234   EXPECT_THROW(
1235       IPAddressV6::longestCommonPrefix(
1236           {ip6.asV6(), IPAddressV6::bitCount() + 1},
1237           {ip6.asV6(), IPAddressV6::bitCount()}),
1238       std::invalid_argument);
1239 }
1240
1241 static const vector<AddressData> validAddressProvider = {
1242     AddressData("127.0.0.1", {127, 0, 0, 1}, 4),
1243     AddressData("69.63.189.16", {69, 63, 189, 16}, 4),
1244     AddressData("0.0.0.0", {0, 0, 0, 0}, 4),
1245     AddressData("::1", {0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1}, 6),
1246     AddressData(
1247         "2620:0:1cfe:face:b00c::3",
1248         {38, 32, 0, 0, 28, 254, 250, 206, 176, 12, 0, 0, 0, 0, 0, 3},
1249         6),
1250 };
1251
1252 static const vector<string> invalidAddressProvider = {
1253     "",
1254     "foo",
1255     "1.1.1.256",
1256     "1",
1257     ":1",
1258     "127.0.0.1,127.0.0.1",
1259     "[1234]",
1260 };
1261
1262 static const vector<ByteVector> invalidBinaryProvider = {
1263     {0x31, 0x32, 0x37, 0x2e, 0x30, 0x30, 0x2e, 0x30, 0x2e, 0x31},
1264     // foo
1265     {0x66, 0x6f, 0x6f},
1266     {0x00},
1267     {0x00, 0x00},
1268     {0x00, 0x00, 0x00},
1269     {0x00, 0x00, 0x00, 0x00, 0x00},
1270     {0xff},
1271 };
1272
1273 static const uint8_t IS_LOCAL = AddressFlags::IS_LOCAL;
1274 static const uint8_t IS_NONROUTABLE = AddressFlags::IS_NONROUTABLE;
1275 static const uint8_t IS_PRIVATE = AddressFlags::IS_PRIVATE;
1276 static const uint8_t IS_ZERO = AddressFlags::IS_ZERO;
1277 static const uint8_t IS_LINK_LOCAL =
1278     AddressFlags::IS_LINK_LOCAL | IS_NONROUTABLE;
1279 static const uint8_t IS_PVT_NONROUTE = IS_NONROUTABLE | IS_PRIVATE;
1280 static const uint8_t IS_MULTICAST = AddressFlags::IS_MULTICAST;
1281 static const uint8_t IS_LINK_LOCAL_BROADCAST =
1282     AddressFlags::IS_LINK_LOCAL_BROADCAST;
1283
1284 static vector<AddressFlags> flagProvider = {
1285     // public v4
1286     AddressFlags("69.63.176.1", 4, 0),
1287     AddressFlags("128.12.65.3", 4, 0),
1288     AddressFlags("192.0.1.0", 4, 0),
1289     AddressFlags("198.51.101.0", 4, 0),
1290     AddressFlags("203.0.114.0", 4, 0),
1291     AddressFlags("128.12.64.115", 4, 0),
1292
1293     // public v6
1294     AddressFlags("2620:0:1cfe:face:b00c::3", 6, 0),
1295
1296     // localhost
1297     AddressFlags("127.0.0.1", 4, IS_LOCAL | IS_PVT_NONROUTE),
1298     AddressFlags("::1", 6, IS_LOCAL | IS_PVT_NONROUTE),
1299
1300     // link-local v4
1301     AddressFlags("169.254.0.1", 4, IS_LINK_LOCAL | IS_PVT_NONROUTE),
1302
1303     // private v4
1304     AddressFlags("10.0.0.0", 4, IS_PVT_NONROUTE),
1305     AddressFlags("10.11.12.13", 4, IS_PVT_NONROUTE),
1306     AddressFlags("10.255.255.255", 4, IS_PVT_NONROUTE),
1307     AddressFlags("127.128.129.200", 4, IS_LOCAL | IS_PVT_NONROUTE),
1308     AddressFlags("127.255.255.255", 4, IS_LOCAL | IS_PVT_NONROUTE),
1309     AddressFlags("169.254.0.0", 4, IS_LINK_LOCAL | IS_PVT_NONROUTE),
1310     AddressFlags("192.168.0.0", 4, IS_PVT_NONROUTE),
1311     AddressFlags("192.168.200.255", 4, IS_PVT_NONROUTE),
1312     AddressFlags("192.168.255.255", 4, IS_PVT_NONROUTE),
1313
1314     // private v6
1315     AddressFlags("fd01:1637:1c56:66af::", 6, IS_PVT_NONROUTE),
1316
1317     // non routable v4
1318     AddressFlags("0.0.0.0", 4, IS_NONROUTABLE | IS_ZERO),
1319     AddressFlags("0.255.255.255", 4, IS_NONROUTABLE),
1320     AddressFlags("192.0.0.0", 4, IS_NONROUTABLE),
1321     AddressFlags("192.0.2.0", 4, IS_NONROUTABLE),
1322     AddressFlags("198.18.0.0", 4, IS_NONROUTABLE),
1323     AddressFlags("198.19.255.255", 4, IS_NONROUTABLE),
1324     AddressFlags("198.51.100.0", 4, IS_NONROUTABLE),
1325     AddressFlags("198.51.100.255", 4, IS_NONROUTABLE),
1326     AddressFlags("203.0.113.0", 4, IS_NONROUTABLE),
1327     AddressFlags("203.0.113.255", 4, IS_NONROUTABLE),
1328     AddressFlags("224.0.0.0", 4, IS_NONROUTABLE | IS_MULTICAST),
1329     AddressFlags("240.0.0.0", 4, IS_NONROUTABLE),
1330     AddressFlags("224.0.0.0", 4, IS_NONROUTABLE),
1331     // v4 link local broadcast
1332     AddressFlags(
1333         "255.255.255.255",
1334         4,
1335         IS_NONROUTABLE | IS_LINK_LOCAL_BROADCAST),
1336
1337     // non routable v6
1338     AddressFlags("1999::1", 6, IS_NONROUTABLE),
1339     AddressFlags("0::0", 6, IS_NONROUTABLE | IS_ZERO),
1340     AddressFlags("0::0:0", 6, IS_NONROUTABLE | IS_ZERO),
1341     AddressFlags("0:0:0::0", 6, IS_NONROUTABLE | IS_ZERO),
1342
1343     // link-local v6
1344     AddressFlags("fe80::0205:73ff:fef9:46fc", 6, IS_LINK_LOCAL),
1345     AddressFlags("fe80::0012:34ff:fe56:7890", 6, IS_LINK_LOCAL),
1346
1347     // multicast v4
1348     AddressFlags("224.0.0.1", 4, IS_MULTICAST | IS_NONROUTABLE),
1349     AddressFlags("224.0.0.251", 4, IS_MULTICAST | IS_NONROUTABLE),
1350     AddressFlags("239.12.34.56", 4, IS_MULTICAST | IS_NONROUTABLE),
1351
1352     // multicast v6
1353     AddressFlags("ff00::", 6, IS_MULTICAST | IS_NONROUTABLE),
1354     AddressFlags("ff02:ffff::1", 6, IS_MULTICAST | IS_NONROUTABLE),
1355     AddressFlags("ff02::101", 6, IS_MULTICAST | IS_NONROUTABLE),
1356     AddressFlags("ff0e::101", 6, IS_MULTICAST),
1357     // v6 link local broadcast
1358     AddressFlags("ff02::1", 6, IS_NONROUTABLE | IS_LINK_LOCAL_BROADCAST),
1359 };
1360
1361 static const vector<pair<string, string>> mapProvider = {
1362     {"::ffff:192.0.2.128", "192.0.2.128"},
1363     {"192.0.2.128", "::ffff:192.0.2.128"},
1364     {"::FFFF:129.144.52.38", "129.144.52.38"},
1365     {"129.144.52.38", "::FFFF:129.144.52.38"},
1366     {"0:0:0:0:0:FFFF:222.1.41.90", "222.1.41.90"},
1367     {"::FFFF:222.1.41.90", "222.1.41.90"},
1368 };
1369
1370 static const vector<MaskData> masksProvider = {
1371     MaskData("255.255.255.255", 1, "128.0.0.0"),
1372     MaskData("255.255.255.255", 2, "192.0.0.0"),
1373     MaskData("192.0.2.42", 16, "192.0.0.0"),
1374     MaskData("255.255.255.255", 24, "255.255.255.0"),
1375     MaskData("255.255.255.255", 32, "255.255.255.255"),
1376     MaskData("10.10.10.10", 0, "0.0.0.0"),
1377     MaskData("::1", 64, "::"),
1378     MaskData("2620:0:1cfe:face:b00c::3", 1, "::"),
1379     MaskData("2620:0:1cfe:face:b00c::3", 3, "2000::"),
1380     MaskData("2620:0:1cfe:face:b00c::3", 6, "2400::"),
1381     MaskData("2620:0:1cfe:face:b00c::3", 7, "2600::"),
1382     MaskData("2620:0:1cfe:face:b00c::3", 11, "2620::"),
1383     MaskData("2620:0:1cfe:face:b00c::3", 36, "2620:0:1000::"),
1384     MaskData("2620:0:1cfe:face:b00c::3", 37, "2620:0:1800::"),
1385     MaskData("2620:0:1cfe:face:b00c::3", 38, "2620:0:1c00::"),
1386     MaskData("2620:0:1cfe:face:b00c::3", 41, "2620:0:1c80::"),
1387     MaskData("2620:0:1cfe:face:b00c::3", 42, "2620:0:1cc0::"),
1388     MaskData("2620:0:1cfe:face:b00c::3", 43, "2620:0:1ce0::"),
1389     MaskData("2620:0:1cfe:face:b00c::3", 44, "2620:0:1cf0::"),
1390     MaskData("2620:0:1cfe:face:b00c::3", 45, "2620:0:1cf8::"),
1391     MaskData("2620:0:1cfe:face:b00c::3", 46, "2620:0:1cfc::"),
1392     MaskData("2620:0:1cfe:face:b00c::3", 47, "2620:0:1cfe::"),
1393     MaskData("2620:0:1cfe:face:b00c::3", 49, "2620:0:1cfe:8000::"),
1394     MaskData("2620:0:1cfe:face:b00c::3", 50, "2620:0:1cfe:c000::"),
1395     MaskData("2620:0:1cfe:face:b00c::3", 51, "2620:0:1cfe:e000::"),
1396     MaskData("2620:0:1cfe:face:b00c::3", 52, "2620:0:1cfe:f000::"),
1397     MaskData("2620:0:1cfe:face:b00c::3", 53, "2620:0:1cfe:f800::"),
1398     MaskData("2620:0:1cfe:face:b00c::3", 55, "2620:0:1cfe:fa00::"),
1399     MaskData("2620:0:1cfe:face:b00c::3", 57, "2620:0:1cfe:fa80::"),
1400     MaskData("2620:0:1cfe:face:b00c::3", 58, "2620:0:1cfe:fac0::"),
1401     MaskData("2620:0:1cfe:face:b00c::3", 61, "2620:0:1cfe:fac8::"),
1402     MaskData("2620:0:1cfe:face:b00c::3", 62, "2620:0:1cfe:facc::"),
1403     MaskData("2620:0:1cfe:face:b00c::3", 63, "2620:0:1cfe:face::"),
1404     MaskData("2620:0:1cfe:face:b00c::3", 65, "2620:0:1cfe:face:8000::"),
1405     MaskData("2620:0:1cfe:face:b00c::3", 67, "2620:0:1cfe:face:a000::"),
1406     MaskData("2620:0:1cfe:face:b00c::3", 68, "2620:0:1cfe:face:b000::"),
1407     MaskData("2620:0:1cfe:face:b00c::3", 77, "2620:0:1cfe:face:b008::"),
1408     MaskData("2620:0:1cfe:face:b00c::3", 78, "2620:0:1cfe:face:b00c::"),
1409     MaskData("2620:0:1cfe:face:b00c::3", 127, "2620:0:1cfe:face:b00c::2"),
1410     MaskData("2620:0:1cfe:face:b00c::3", 128, "2620:0:1cfe:face:b00c::3"),
1411     MaskData("2620:0:1cfe:face:b00c::3", 0, "::"),
1412 };
1413
1414 static const vector<MaskBoundaryData> maskBoundaryProvider = {
1415     MaskBoundaryData("10.1.1.1", 24, "10.1.1.1", true),
1416     MaskBoundaryData("10.1.1.1", 8, "10.1.2.3", true),
1417     MaskBoundaryData("2620:0:1cfe:face:b00c::1", 48, "2620:0:1cfe::", true),
1418     // addresses that are NOT in the same subnet once mask is applied
1419     MaskBoundaryData("10.1.1.1", 24, "10.1.2.1", false),
1420     MaskBoundaryData("10.1.1.1", 16, "10.2.3.4", false),
1421     MaskBoundaryData("2620:0:1cfe:face:b00c::1", 48, "2620:0:1cfc::", false),
1422 };
1423
1424 INSTANTIATE_TEST_CASE_P(
1425     IPAddress,
1426     IPAddressTest,
1427     ::testing::ValuesIn(validAddressProvider));
1428 INSTANTIATE_TEST_CASE_P(
1429     IPAddress,
1430     IPAddressFlagTest,
1431     ::testing::ValuesIn(flagProvider));
1432 INSTANTIATE_TEST_CASE_P(
1433     IPAddress,
1434     IPAddressMappedTest,
1435     ::testing::ValuesIn(mapProvider));
1436 INSTANTIATE_TEST_CASE_P(
1437     IPAddress,
1438     IPAddressCtorTest,
1439     ::testing::ValuesIn(invalidAddressProvider));
1440 INSTANTIATE_TEST_CASE_P(
1441     IPAddress,
1442     IPAddressCtorBinaryTest,
1443     ::testing::ValuesIn(invalidBinaryProvider));
1444 INSTANTIATE_TEST_CASE_P(
1445     IPAddress,
1446     IPAddressMaskTest,
1447     ::testing::ValuesIn(masksProvider));
1448 INSTANTIATE_TEST_CASE_P(
1449     IPAddress,
1450     IPAddressMaskBoundaryTest,
1451     ::testing::ValuesIn(maskBoundaryProvider));
1452 INSTANTIATE_TEST_CASE_P(
1453     IPAddress,
1454     IPAddressByteAccessorTest,
1455     ::testing::ValuesIn(validAddressProvider));
1456 INSTANTIATE_TEST_CASE_P(
1457     IPAddress,
1458     IPAddressBitAccessorTest,
1459     ::testing::ValuesIn(validAddressProvider));
1460
1461 TEST(IPAddressV4, fetchMask) {
1462   struct X : private IPAddressV4 {
1463     using IPAddressV4::fetchMask;
1464   };
1465
1466   EXPECT_THAT(
1467       X::fetchMask(0),
1468       ::testing::ElementsAreArray(ByteArray4{{0x00, 0x00, 0x00, 0x00}}));
1469
1470   EXPECT_THAT(
1471       X::fetchMask(1),
1472       ::testing::ElementsAreArray(ByteArray4{{0x80, 0x00, 0x00, 0x00}}));
1473
1474   EXPECT_THAT(
1475       X::fetchMask(31),
1476       ::testing::ElementsAreArray(ByteArray4{{0xff, 0xff, 0xff, 0xfe}}));
1477
1478   EXPECT_THAT(
1479       X::fetchMask(32),
1480       ::testing::ElementsAreArray(ByteArray4{{0xff, 0xff, 0xff, 0xff}}));
1481 }
1482
1483 TEST(IPAddressV6, fetchMask) {
1484   struct X : private IPAddressV6 {
1485     using IPAddressV6::fetchMask;
1486   };
1487
1488   EXPECT_THAT(
1489       X::fetchMask(0),
1490       ::testing::ElementsAreArray(join8({{
1491           ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1492           ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1493       }})));
1494
1495   EXPECT_THAT(
1496       X::fetchMask(1),
1497       ::testing::ElementsAreArray(join8({{
1498           ByteArray8{{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1499           ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1500       }})));
1501
1502   EXPECT_THAT(
1503       X::fetchMask(63),
1504       ::testing::ElementsAreArray(join8({{
1505           ByteArray8{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}},
1506           ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1507       }})));
1508
1509   EXPECT_THAT(
1510       X::fetchMask(64),
1511       ::testing::ElementsAreArray(join8({{
1512           ByteArray8{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
1513           ByteArray8{{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1514       }})));
1515
1516   EXPECT_THAT(
1517       X::fetchMask(65),
1518       ::testing::ElementsAreArray(join8({{
1519           ByteArray8{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
1520           ByteArray8{{0x80, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
1521       }})));
1522
1523   EXPECT_THAT(
1524       X::fetchMask(127),
1525       ::testing::ElementsAreArray(join8({{
1526           ByteArray8{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
1527           ByteArray8{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xfe}},
1528       }})));
1529
1530   EXPECT_THAT(
1531       X::fetchMask(128),
1532       ::testing::ElementsAreArray(join8({{
1533           ByteArray8{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
1534           ByteArray8{{0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff, 0xff}},
1535       }})));
1536 }