Fibers allocation/deallocation benchmarks
[folly.git] / folly / test / IPAddressTest.cpp
index b9cb43de254b5f9db99b7e173c0734f402c09ceb..f603fe122e6d151f828699ca6b1508b2509ddb51 100644 (file)
@@ -1,5 +1,5 @@
 /*
- * Copyright 2014 Facebook, Inc.
+ * Copyright 2015 Facebook, Inc.
  *
  * Licensed under the Apache License, Version 2.0 (the "License");
  * you may not use this file except in compliance with the License.
  * limitations under the License.
  */
 
-#include "IPAddressTest.h"
+#include <folly/test/IPAddressTest.h>
 
 #include <gtest/gtest.h>
 
-#include "folly/Bits.h"
-#include "folly/Format.h"
-#include "folly/String.h"
-#include "folly/MacAddress.h"
+#include <folly/Bits.h>
+#include <folly/Format.h>
+#include <folly/String.h>
+#include <folly/MacAddress.h>
 
 using namespace folly;
 using namespace std;
@@ -29,16 +29,22 @@ using namespace std;
 // tests code example
 TEST(IPAddress, CodeExample) {
   EXPECT_EQ(4, sizeof(IPAddressV4));
-  EXPECT_EQ(16, sizeof(IPAddressV6));
-  EXPECT_EQ(20, sizeof(IPAddress));
+  EXPECT_EQ(20, sizeof(IPAddressV6));
+  EXPECT_EQ(24, sizeof(IPAddress));
+  IPAddress uninitaddr;
   IPAddress v4addr("192.0.2.129");
   IPAddress v6map("::ffff:192.0.2.129");
+  ASSERT_TRUE(uninitaddr.empty());
+  ASSERT_FALSE(v4addr.empty());
+  ASSERT_FALSE(v6map.empty());
   EXPECT_TRUE(v4addr.inSubnet("192.0.2.0/24"));
   EXPECT_TRUE(v4addr.inSubnet(IPAddress("192.0.2.0"), 24));
   EXPECT_TRUE(v4addr.inSubnet("192.0.2.128/30"));
   EXPECT_FALSE(v4addr.inSubnet("192.0.2.128/32"));
   EXPECT_EQ(2164392128, v4addr.asV4().toLong());
   EXPECT_EQ(3221226113, v4addr.asV4().toLongHBO());
+  ASSERT_FALSE(uninitaddr.isV4());
+  ASSERT_FALSE(uninitaddr.isV6());
   ASSERT_TRUE(v4addr.isV4());
   ASSERT_TRUE(v6map.isV6());
   EXPECT_TRUE(v4addr == v6map);
@@ -47,6 +53,24 @@ TEST(IPAddress, CodeExample) {
   EXPECT_TRUE(IPAddress::createIPv6(v4addr) == v6map.asV6());
 }
 
+TEST(IPAddress, Scope) {
+  // Test that link-local scope is saved
+  auto str = "fe80::62eb:69ff:fe9b:ba60%eth0";
+  IPAddressV6 a2(str);
+  EXPECT_EQ(str, a2.str());
+
+  sockaddr_in6 sock = a2.toSockAddr();
+  EXPECT_NE(0, sock.sin6_scope_id);
+
+  IPAddress a1(str);
+  EXPECT_EQ(str, a1.str());
+
+  a2.setScopeId(0);
+  EXPECT_NE(a1, a2);
+
+  EXPECT_TRUE(a2 < a1);
+}
+
 TEST(IPAddress, Ordering) {
   IPAddress a1("0.1.1.1");
   IPAddress a2("1.1.1.0");
@@ -266,6 +290,7 @@ TEST(IPAddress, CtorSockaddr) {
   {
     // setup
     sockaddr_in6 addr;
+    memset(&addr, 0, sizeof(addr));
     in6_addr sin_addr;
     ByteArray16 sec{{
       // 2620:0:1cfe:face:b00c::3
@@ -384,6 +409,11 @@ TEST(IPAddress, ToFullyQualifiedLocal) {
   EXPECT_EQ("0000:0000:0000:0000:0000:0000:0000:0001", ip.toFullyQualified())
       << ip;
 }
+TEST(IPAddress, ToFullyQualifiedSize) {
+  auto actual = IPAddressV6::kToFullyQualifiedSize;
+  auto expected = IPAddress("::").toFullyQualified().size();
+  EXPECT_EQ(expected, actual);
+}
 
 // test v4-v6 mapped addresses
 TEST_P(IPAddressMappedTest, MappedEqual) {
@@ -435,6 +465,26 @@ TEST_P(IPAddressMaskBoundaryTest, NonMaskedSubnet) {
   EXPECT_EQ(param.inSubnet, ip.inSubnet(subnet, param.mask));
 }
 
+TEST(IPAddress, UnitializedEqual) {
+  IPAddress addrEmpty;
+  IPAddress ip4("127.0.0.1");
+  EXPECT_FALSE(addrEmpty == ip4);
+  EXPECT_FALSE(ip4 == addrEmpty);
+  IPAddress ip6("::1");
+  EXPECT_FALSE(addrEmpty == ip6);
+  EXPECT_FALSE(ip6 == addrEmpty);
+  IPAddress ip6Map("::ffff:192.0.2.129");
+  EXPECT_FALSE(addrEmpty == ip6Map);
+  EXPECT_FALSE(ip6Map == addrEmpty);
+  IPAddress ip4Zero("0.0.0.0");
+  EXPECT_FALSE(addrEmpty == ip4Zero);
+  EXPECT_FALSE(ip4Zero == addrEmpty);
+  IPAddress ip6Zero("::");
+  EXPECT_FALSE(addrEmpty == ip6Zero);
+  EXPECT_FALSE(ip6Zero == addrEmpty);
+  EXPECT_EQ(addrEmpty, addrEmpty);
+}
+
 // Test subnet calcs with 6to4 addresses
 TEST(IPAddress, InSubnetWith6to4) {
   auto ip = IPAddress("2002:c000:022a::"); // 192.0.2.42
@@ -450,19 +500,35 @@ TEST(IPAddress, InSubnetWith6to4) {
   EXPECT_TRUE(ip3.inSubnet(subnet3, 16));
 }
 
-static vector<pair<string, uint8_t> > invalidMasks = {
+static const vector<string> ipv4Strs = {
+  "127.0.0.1",
+  "198.168.0.1",
+  "8.8.0.0",
+};
+TEST(IPAddress, getIPv6For6To4) {
+  for (auto ipv4Str : ipv4Strs) {
+    auto ip = IPAddress(ipv4Str);
+    EXPECT_TRUE(ip.isV4());
+    IPAddressV4 ipv4 = ip.asV4();
+    auto ipv6 = ipv4.getIPv6For6To4();
+    EXPECT_EQ(ipv6.type(), IPAddressV6::Type::T6TO4);
+    auto ipv4New = ipv6.getIPv4For6To4();
+    EXPECT_TRUE(ipv4Str.compare(ipv4New.str()) == 0);
+  }
+}
+
+static const vector<pair<string, uint8_t> > invalidMasks = {
   {"127.0.0.1", 33},
   {"::1", 129},
 };
 TEST(IPAddress, InvalidMask) {
   for (auto& tc : invalidMasks) {
-    uint8_t mask = tc.second;
     auto ip = IPAddress(tc.first);
     EXPECT_THROW(ip.mask(tc.second), IPAddressFormatException);
   }
 }
 
-static vector<pair<string, IPAddressV6::Type> > v6types = {
+static const vector<pair<string, IPAddressV6::Type> > v6types = {
   {"::1", IPAddressV6::Type::NORMAL},
   {"2620:0:1cfe:face:b00c::3", IPAddressV6::Type::NORMAL},
   {"2001:0000:4136:e378:8000:63bf:3fff:fdd2", IPAddressV6::Type::TEREDO},
@@ -506,7 +572,7 @@ TEST(IPAddress, V6Types) {
   }
 }
 
-static vector<pair<string, uint32_t> > provideToLong = {
+static const vector<pair<string, uint32_t> > provideToLong = {
   {"0.0.0.0", 0},
   {"10.0.0.0", 167772160},
   {"126.131.128.23", 2122547223},
@@ -565,7 +631,7 @@ TEST(IPAddress, fromBinaryV4) {
                IPAddressFormatException);
 }
 
-static vector<pair<string, vector<uint8_t> > > provideBinary16Bytes = {
+static const vector<pair<string, vector<uint8_t> > > provideBinary16Bytes = {
   {"::0",
     {0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
      0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00}},
@@ -645,10 +711,7 @@ TEST_P(IPAddressFlagTest, IsZero) {
 
 TEST_P(IPAddressFlagTest, IsLinkLocal) {
   AddressFlags param = GetParam();
-  if (param.version != 6) {
-    return;
-  }
-  IPAddressV6 addr(param.address);
+  IPAddress addr(param.address);
   EXPECT_EQ(param.isLinkLocal(), addr.isLinkLocal()) << addr;
 }
 
@@ -681,7 +744,7 @@ TEST(IPAddress, SolicitedNodeAddress) {
 TEST_P(IPAddressByteAccessorTest, CheckBytes) {
   auto addrData = GetParam();
   IPAddress ip(addrData.address);
-  auto i = 0;
+  size_t i = 0;
   for (auto byitr = addrData.bytes.begin(); i < ip.byteCount(); ++i, ++byitr) {
     EXPECT_EQ(*byitr, ip.getNthMSByte(i));
     EXPECT_EQ(*byitr, ip.isV4() ?
@@ -705,7 +768,7 @@ TEST_P(IPAddressBitAccessorTest, CheckBits) {
   //We will traverse the IPAddress bits from 0 to bitCount -1
   auto bitr = folly::makeBitIterator(littleEndianAddrData.begin());
   IPAddress ip(addrData.address);
-  for (auto i = 0; i < ip.bitCount(); ++i) {
+  for (size_t i = 0; i < ip.bitCount(); ++i) {
     auto msbIndex = ip.bitCount() - i - 1;
     EXPECT_EQ(*bitr, ip.getNthMSBit(msbIndex));
     EXPECT_EQ(*bitr, ip.isV4() ? ip.asV4().getNthMSBit(msbIndex) :
@@ -768,6 +831,19 @@ TEST(IPAddress, InvalidBBitAccess) {
   EXPECT_THROW(asV6.getNthLSBit(-1), std::invalid_argument);
 }
 
+TEST(IPAddress, StringFormat) {
+  in6_addr a6;
+  for (int i = 0; i < 8; ++i) {
+    a6.s6_addr16[i] = htons(0x0123 + ((i%4) * 0x4444));
+  }
+  EXPECT_EQ("0123:4567:89ab:cdef:0123:4567:89ab:cdef",
+            detail::fastIpv6ToString(a6));
+
+  in_addr a4;
+  a4.s_addr = htonl(0x01020304);
+  EXPECT_EQ("1.2.3.4", detail::fastIpv4ToString(a4));
+}
+
 TEST(IPAddress, LongestCommonPrefix) {
   IPAddress ip10("10.0.0.0");
   IPAddress ip11("11.0.0.0");
@@ -851,7 +927,7 @@ TEST(IPAddress, LongestCommonPrefix) {
 
 }
 
-static vector<AddressData> validAddressProvider = {
+static const vector<AddressData> validAddressProvider = {
   AddressData("127.0.0.1", {127,0,0,1}, 4),
   AddressData("69.63.189.16", {69,63,189,16}, 4),
   AddressData("0.0.0.0", {0,0,0,0}, 4),
@@ -861,7 +937,7 @@ static vector<AddressData> validAddressProvider = {
               {38,32,0,0,28,254,250,206,176,12,0,0,0,0,0,3}, 6),
 };
 
-static vector<string> invalidAddressProvider = {
+static const vector<string> invalidAddressProvider = {
   "",
   "foo",
   "1.1.1.256",
@@ -871,7 +947,7 @@ static vector<string> invalidAddressProvider = {
   "[1234]",
 };
 
-static vector<ByteVector> invalidBinaryProvider = {
+static const vector<ByteVector> invalidBinaryProvider = {
   {0x31, 0x32, 0x37, 0x2e, 0x30, 0x30, 0x2e, 0x30, 0x2e, 0x31},
   // foo
   {0x66, 0x6f, 0x6f},
@@ -909,13 +985,16 @@ static vector<AddressFlags> flagProvider = {
   AddressFlags("127.0.0.1", 4, IS_LOCAL | IS_PVT_NONROUTE),
   AddressFlags("::1", 6, IS_LOCAL | IS_PVT_NONROUTE),
 
+  // link-local v4
+  AddressFlags("169.254.0.1", 4, IS_LINK_LOCAL | IS_PVT_NONROUTE),
+
   // private v4
   AddressFlags("10.0.0.0", 4, IS_PVT_NONROUTE),
   AddressFlags("10.11.12.13", 4, IS_PVT_NONROUTE),
   AddressFlags("10.255.255.255", 4, IS_PVT_NONROUTE),
-  AddressFlags("127.128.129.200", 4, IS_PVT_NONROUTE),
-  AddressFlags("127.255.255.255", 4, IS_PVT_NONROUTE),
-  AddressFlags("169.254.0.0", 4, IS_PVT_NONROUTE),
+  AddressFlags("127.128.129.200", 4, IS_LOCAL | IS_PVT_NONROUTE),
+  AddressFlags("127.255.255.255", 4, IS_LOCAL | IS_PVT_NONROUTE),
+  AddressFlags("169.254.0.0", 4, IS_LINK_LOCAL | IS_PVT_NONROUTE),
   AddressFlags("192.168.0.0", 4, IS_PVT_NONROUTE),
   AddressFlags("192.168.200.255", 4, IS_PVT_NONROUTE),
   AddressFlags("192.168.255.255", 4, IS_PVT_NONROUTE),
@@ -964,7 +1043,7 @@ static vector<AddressFlags> flagProvider = {
   AddressFlags("ff02::1", 6, IS_NONROUTABLE | IS_LINK_LOCAL_BROADCAST),
 };
 
-static vector<pair<string, string> > mapProvider = {
+static const vector<pair<string, string> > mapProvider = {
   {"::ffff:192.0.2.128", "192.0.2.128"},
   {"192.0.2.128", "::ffff:192.0.2.128"},
   {"::FFFF:129.144.52.38", "129.144.52.38"},
@@ -973,7 +1052,7 @@ static vector<pair<string, string> > mapProvider = {
   {"::FFFF:222.1.41.90", "222.1.41.90"},
 };
 
-static vector<MaskData> masksProvider = {
+static const vector<MaskData> masksProvider = {
   MaskData("255.255.255.255", 1, "128.0.0.0"),
   MaskData("255.255.255.255", 2, "192.0.0.0"),
   MaskData("192.0.2.42", 16, "192.0.0.0"),
@@ -1017,7 +1096,7 @@ static vector<MaskData> masksProvider = {
   MaskData("2620:0:1cfe:face:b00c::3", 0, "::")
 };
 
-static vector<MaskBoundaryData> maskBoundaryProvider = {
+static const vector<MaskBoundaryData> maskBoundaryProvider = {
   MaskBoundaryData("10.1.1.1", 24, "10.1.1.1", true),
   MaskBoundaryData("10.1.1.1", 8, "10.1.2.3", true),
   MaskBoundaryData("2620:0:1cfe:face:b00c::1", 48, "2620:0:1cfe::", true),