This is an automated email from the ASF dual-hosted git repository.

awong pushed a commit to branch master
in repository https://gitbox.apache.org/repos/asf/kudu.git

commit c2f4cf7b8b3240feef6ec0060c99f78d3744d76d
Author: Andrew Wong <[email protected]>
AuthorDate: Wed Jun 9 12:42:31 2021 -0700

    [util] flag to specify hosts to fail DNS resolution
    
    This patch adds a flag to specify the specific hostports to which
    failures are injected by --fail_dns_resolution. I intend on using this
    in a subsequent patch.
    
    Change-Id: I25f2d3073fa0fa0a430afacf7c8cd1402e6bd6ab
    Reviewed-on: http://gerrit.cloudera.org:8080/17584
    Reviewed-by: Alexey Serbin <[email protected]>
    Tested-by: Andrew Wong <[email protected]>
---
 src/kudu/util/net/net_util-test.cc | 39 ++++++++++++++++++++++++++++++++++++++
 src/kudu/util/net/net_util.cc      | 24 +++++++++++++++++++++--
 2 files changed, 61 insertions(+), 2 deletions(-)

diff --git a/src/kudu/util/net/net_util-test.cc 
b/src/kudu/util/net/net_util-test.cc
index ae85220..c409b2b 100644
--- a/src/kudu/util/net/net_util-test.cc
+++ b/src/kudu/util/net/net_util-test.cc
@@ -25,10 +25,12 @@
 #include <string>
 #include <vector>
 
+#include <gflags/gflags_declare.h>
 #include <glog/logging.h>
 #include <gtest/gtest.h>
 
 #include "kudu/gutil/strings/join.h"
+#include "kudu/gutil/strings/substitute.h"
 #include "kudu/gutil/strings/util.h"
 #include "kudu/util/net/sockaddr.h"
 #include "kudu/util/net/socket.h"
@@ -36,8 +38,12 @@
 #include "kudu/util/test_macros.h"
 #include "kudu/util/test_util.h"
 
+DECLARE_bool(fail_dns_resolution);
+DECLARE_string(fail_dns_resolution_hostports);
+
 using std::string;
 using std::vector;
+using strings::Substitute;
 
 namespace kudu {
 
@@ -128,6 +134,39 @@ TEST_F(NetUtilTest, TestParseAddressesWithScheme) {
   ASSERT_STR_CONTAINS(s.ToString(), "invalid scheme format");
 }
 
+TEST_F(NetUtilTest, TestInjectFailureToResolveAddresses) {
+  HostPort hp1("localhost", 12345);
+  HostPort hp2("localhost", 12346);
+  FLAGS_fail_dns_resolution_hostports = hp1.ToString();
+  FLAGS_fail_dns_resolution = true;
+
+  // With a list of bad hostports specified, check that resolution fails as
+  // expected.
+  vector<Sockaddr> addrs;
+  Status s = hp1.ResolveAddresses(&addrs);
+  ASSERT_TRUE(s.IsNetworkError()) << s.ToString();
+
+  // Addresses not in the list should resolve fine.
+  ASSERT_TRUE(addrs.empty());
+  ASSERT_OK(hp2.ResolveAddresses(&addrs));
+  ASSERT_FALSE(addrs.empty());
+
+  // With both in the list, resolution should fail.
+  FLAGS_fail_dns_resolution_hostports = Substitute("$0,$1", hp1.ToString(), 
hp2.ToString());
+  addrs.clear();
+  s = hp1.ResolveAddresses(&addrs);
+  ASSERT_TRUE(s.IsNetworkError()) << s.ToString();
+  s = hp2.ResolveAddresses(&addrs);
+  ASSERT_TRUE(s.IsNetworkError()) << s.ToString();
+
+  // When a list isn't specified, all resolution fails.
+  FLAGS_fail_dns_resolution_hostports = "";
+  s = hp1.ResolveAddresses(&addrs);
+  ASSERT_TRUE(s.IsNetworkError()) << s.ToString();
+  s = hp2.ResolveAddresses(&addrs);
+  ASSERT_TRUE(s.IsNetworkError()) << s.ToString();
+}
+
 TEST_F(NetUtilTest, TestResolveAddresses) {
   HostPort hp("localhost", 12345);
   vector<Sockaddr> addrs;
diff --git a/src/kudu/util/net/net_util.cc b/src/kudu/util/net/net_util.cc
index edfa8e6..ce5e156 100644
--- a/src/kudu/util/net/net_util.cc
+++ b/src/kudu/util/net/net_util.cc
@@ -64,14 +64,19 @@
 #define HOST_NAME_MAX 64
 #endif
 
-DEFINE_bool(fail_dns_resolution, false, "Whether to fail all dns resolution, 
for tests.");
+DEFINE_bool(fail_dns_resolution, false, "Whether to fail dns resolution, for 
tests.");
 TAG_FLAG(fail_dns_resolution, hidden);
+DEFINE_string(fail_dns_resolution_hostports, "",
+              "Comma-separated list of hostports that fail dns resolution. If 
empty, fails all "
+              "dns resolution attempts. Only takes effect if 
--fail_dns_resolution is 'true'.");
+TAG_FLAG(fail_dns_resolution_hostports, hidden);
 
 using std::function;
 using std::string;
 using std::unordered_set;
 using std::unique_ptr;
 using std::vector;
+using strings::Split;
 using strings::Substitute;
 
 namespace kudu {
@@ -215,7 +220,22 @@ Status HostPort::ResolveAddresses(vector<Sockaddr>* 
addresses) const {
     }
   }
   if (PREDICT_FALSE(FLAGS_fail_dns_resolution)) {
-    return Status::NetworkError("injected DNS resolution failure");
+    if (FLAGS_fail_dns_resolution_hostports.empty()) {
+      return Status::NetworkError("injected DNS resolution failure");
+    }
+    unordered_set<string> failed_hostports =
+        Split(FLAGS_fail_dns_resolution_hostports, ",");
+    for (const auto& hp_str : failed_hostports) {
+      HostPort hp;
+      Status s = hp.ParseString(hp_str, /*default_port=*/0);
+      if (!s.ok()) {
+        LOG(WARNING) << "Could not parse: " << hp_str;
+        continue;
+      }
+      if (hp == *this) {
+        return Status::NetworkError("injected DNS resolution failure", hp_str);
+      }
+    }
   }
   if (addresses) {
     *addresses = std::move(result_addresses);

Reply via email to