Fix Build: IPv6: SocketAddressTest.SetFromStrings and AsyncSocketTest.ConnectTimeout...
authorYedidya Feldblum <yfeldblum@fb.com>
Fri, 11 Sep 2015 03:21:30 +0000 (20:21 -0700)
committerfacebook-github-bot-9 <folly-bot@fb.com>
Fri, 11 Sep 2015 04:20:17 +0000 (21:20 -0700)
Summary: [Folly] Fix Build: IPv6: `SocketAddressTest.SetFromStrings` and `AsyncSocketTest.ConnectTimeout` failing

On IPv6-only machines, the `SocketAddressTest.SetFromStrings` example in `folly/test/SocketAddressTest.cpp` was failing because it tries to resolve `127.0.0.1` with `AI_ADDRCONFIG` set. Fix it by detecting which of IPv6 and IPv4 are enabled, and picking an appropriate loopback address.

On IPv6-only machines, the `AsyncSocketTest.ConnectTimeout` example in `folly/io/async/test/AsyncSocketTest2.cpp` was failing because it tries to connect `8.8.8.8`, which is IPv4. Fix it by detecting which of IPv6 and IPv4 are enabled, and picking an approprate remote address.

Reviewed By: @chipturner

Differential Revision: D2429109

folly/io/async/test/AsyncSocketTest2.cpp
folly/test/SocketAddressTest.cpp
folly/test/SocketAddressTestHelper.cpp [new file with mode: 0644]
folly/test/SocketAddressTestHelper.h [new file with mode: 0644]

index 0cdf08762f41d71f07f501c0a85ba08c31ca4f5f..66edf663516d8cf2ba1b570fe0a7776d6594e1f7 100644 (file)
@@ -22,6 +22,7 @@
 #include <folly/io/IOBuf.h>
 #include <folly/io/async/test/AsyncSocketTest.h>
 #include <folly/io/async/test/Util.h>
+#include <folly/test/SocketAddressTestHelper.h>
 
 #include <gtest/gtest.h>
 #include <boost/scoped_array.hpp>
@@ -130,7 +131,13 @@ TEST(AsyncSocketTest, ConnectTimeout) {
   // Hopefully this IP will be routable but unresponsive.
   // (Alternatively, we could try listening on a local raw socket, but that
   // normally requires root privileges.)
-  folly::SocketAddress addr("8.8.8.8", 65535);
+  auto host =
+      SocketAddressTestHelper::isIPv6Enabled() ?
+      SocketAddressTestHelper::kGooglePublicDnsAAddrIPv6 :
+      SocketAddressTestHelper::isIPv4Enabled() ?
+      SocketAddressTestHelper::kGooglePublicDnsAAddrIPv4 :
+      nullptr;
+  SocketAddress addr(host, 65535);
   ConnCallback cb;
   socket->connect(&cb, addr, 1); // also set a ridiculously small timeout
 
index 5125cc3797ac0f42badc3579c0f30ea66eb35f29..8a831aa0c553f037e208bbff47009e3fdb86d83c 100644 (file)
 #include <gtest/gtest.h>
 #include <iostream>
 #include <sstream>
+#include <folly/test/SocketAddressTestHelper.h>
 
 using namespace boost;
 using std::string;
 using std::cerr;
 using std::endl;
 using folly::SocketAddress;
+using folly::SocketAddressTestHelper;
 
 TEST(SocketAddress, Size) {
   SocketAddress addr;
@@ -138,9 +140,16 @@ TEST(SocketAddress, SetFromStrings) {
   EXPECT_EQ(addr.getPort(), 80);
 
   // Call setFromLocalIpPort() with an IP and port.
-  addr.setFromLocalIpPort("127.0.0.1:4321");
-  EXPECT_EQ(addr.getAddressStr(), "127.0.0.1");
-  EXPECT_EQ(addr.getPort(), 4321);
+  if (SocketAddressTestHelper::isIPv4Enabled()) {
+    addr.setFromLocalIpPort("127.0.0.1:4321");
+    EXPECT_EQ(addr.getAddressStr(), "127.0.0.1");
+    EXPECT_EQ(addr.getPort(), 4321);
+  }
+  if (SocketAddressTestHelper::isIPv6Enabled()) {
+    addr.setFromLocalIpPort("::1:4321");
+    EXPECT_EQ(addr.getAddressStr(), "::1");
+    EXPECT_EQ(addr.getPort(), 4321);
+  }
 
   // setFromIpPort() without an address should fail
   EXPECT_THROW(addr.setFromIpPort("4321"), std::invalid_argument);
diff --git a/folly/test/SocketAddressTestHelper.cpp b/folly/test/SocketAddressTestHelper.cpp
new file mode 100644 (file)
index 0000000..d24eb0b
--- /dev/null
@@ -0,0 +1,52 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#include <folly/test/SocketAddressTestHelper.h>
+
+#include <sys/socket.h>
+#include <netdb.h>
+#include <glog/logging.h>
+
+namespace folly {
+
+constexpr const char* SocketAddressTestHelper::kLoopbackAddrIPv4;
+constexpr const char* SocketAddressTestHelper::kLoopbackAddrIPv6;
+constexpr const char* SocketAddressTestHelper::kGooglePublicDnsAName;
+constexpr const char* SocketAddressTestHelper::kGooglePublicDnsBName;
+constexpr const char* SocketAddressTestHelper::kGooglePublicDnsAAddrIPv4;
+constexpr const char* SocketAddressTestHelper::kGooglePublicDnsBAddrIPv4;
+constexpr const char* SocketAddressTestHelper::kGooglePublicDnsAAddrIPv6;
+constexpr const char* SocketAddressTestHelper::kGooglePublicDnsBAddrIPv6;
+
+bool SocketAddressTestHelper::isIPv4Enabled() {
+  return isFamilyOfAddrEnabled(kLoopbackAddrIPv4);
+}
+
+bool SocketAddressTestHelper::isIPv6Enabled() {
+  return isFamilyOfAddrEnabled(kLoopbackAddrIPv6);
+}
+
+bool SocketAddressTestHelper::isFamilyOfAddrEnabled(const char* addr) {
+  struct addrinfo hints {};
+  hints.ai_flags = AI_ADDRCONFIG;
+
+  struct addrinfo* resultsp = nullptr;
+  int err = getaddrinfo(addr, nullptr, &hints, &resultsp);
+  freeaddrinfo(resultsp);
+  return !err;
+}
+
+}
diff --git a/folly/test/SocketAddressTestHelper.h b/folly/test/SocketAddressTestHelper.h
new file mode 100644 (file)
index 0000000..fd133e2
--- /dev/null
@@ -0,0 +1,47 @@
+/*
+ * 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.
+ * You may obtain a copy of the License at
+ *
+ *   http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+#pragma once
+
+namespace folly {
+
+class SocketAddressTestHelper {
+ public:
+
+  static constexpr const char* kLoopbackAddrIPv4 = "127.0.0.1";
+  static constexpr const char* kLoopbackAddrIPv6 = "::1";
+
+  //  https://developers.google.com/speed/public-dns/docs/using?hl=en
+  static constexpr const char* kGooglePublicDnsAName =
+    "google-public-dns-a.google.com";
+  static constexpr const char* kGooglePublicDnsBName =
+    "google-public-dns-b.google.com";
+  static constexpr const char* kGooglePublicDnsAAddrIPv4 = "8.8.8.8";
+  static constexpr const char* kGooglePublicDnsBAddrIPv4 = "8.8.4.4";
+  static constexpr const char* kGooglePublicDnsAAddrIPv6 =
+    "2001:4860:4860::8888";
+  static constexpr const char* kGooglePublicDnsBAddrIPv6 =
+    "2001:4860:4860::8844";
+
+  static bool isIPv4Enabled();
+  static bool isIPv6Enabled();
+
+ private:
+
+  static bool isFamilyOfAddrEnabled(const char* addr);
+};
+
+}