aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/cpp/naming/resolver_component_test.cc
diff options
context:
space:
mode:
authorGravatar Jan Tattermusch <jtattermusch@users.noreply.github.com>2018-06-08 11:11:59 +0200
committerGravatar GitHub <noreply@github.com>2018-06-08 11:11:59 +0200
commit61278f3aa72b8032f54728e6847b9655acb38ed2 (patch)
treea2f8f8b62cb51fdc408639be923dadd1e884d663 /test/cpp/naming/resolver_component_test.cc
parent2ea5e1d1dee3d7d7219051723290293901e37fbc (diff)
Revert "Fix shutdown of closed fd when c-ares opens a second fd"
Diffstat (limited to 'test/cpp/naming/resolver_component_test.cc')
-rw-r--r--test/cpp/naming/resolver_component_test.cc110
1 files changed, 3 insertions, 107 deletions
diff --git a/test/cpp/naming/resolver_component_test.cc b/test/cpp/naming/resolver_component_test.cc
index 649441d4fa..f4be064305 100644
--- a/test/cpp/naming/resolver_component_test.cc
+++ b/test/cpp/naming/resolver_component_test.cc
@@ -22,14 +22,10 @@
#include <grpc/support/string_util.h>
#include <grpc/support/sync.h>
#include <grpc/support/time.h>
-
#include <string.h>
-#include <errno.h>
-#include <fcntl.h>
#include <gflags/gflags.h>
#include <gmock/gmock.h>
-#include <thread>
#include <vector>
#include "test/cpp/util/subprocess.h"
@@ -52,12 +48,6 @@
#include "test/core/util/port.h"
#include "test/core/util/test_config.h"
-// TODO: pull in different headers when enabling this
-// test on windows. Also set BAD_SOCKET_RETURN_VAL
-// to INVALID_SOCKET on windows.
-#include "src/core/lib/iomgr/sockaddr_posix.h"
-#define BAD_SOCKET_RETURN_VAL -1
-
using grpc::SubProcess;
using std::vector;
using testing::UnorderedElementsAreArray;
@@ -241,73 +231,7 @@ void CheckLBPolicyResultLocked(grpc_channel_args* channel_args,
}
}
-void OpenAndCloseSocketsStressLoop(int dummy_port, gpr_event* done_ev) {
- // The goal of this loop is to catch socket
- // "use after close" bugs within the c-ares resolver by acting
- // like some separate thread doing I/O.
- // It's goal is to try to hit race conditions whereby:
- // 1) The c-ares resolver closes a socket.
- // 2) This loop opens a socket with (coincidentally) the same handle.
- // 3) the c-ares resolver mistakenly uses that same socket without
- // realizing that its closed.
- // 4) This loop performs an operation on that socket that should
- // succeed but instead fails because of what the c-ares
- // resolver did in the meantime.
- sockaddr_in6 addr;
- memset(&addr, 0, sizeof(addr));
- addr.sin6_family = AF_INET6;
- addr.sin6_port = htons(dummy_port);
- ((char*)&addr.sin6_addr)[15] = 1;
- for (;;) {
- if (gpr_event_get(done_ev)) {
- return;
- }
- std::vector<int> sockets;
- // First open a bunch of sockets, bind and listen
- // '50' is an arbitrary number that, experimentally,
- // has a good chance of catching bugs.
- for (size_t i = 0; i < 50; i++) {
- int s = socket(AF_INET6, SOCK_STREAM, 0);
- int val = 1;
- setsockopt(s, SOL_SOCKET, SO_REUSEPORT, &val, sizeof(val));
- fcntl(s, F_SETFL, O_NONBLOCK);
- ASSERT_TRUE(s != BAD_SOCKET_RETURN_VAL)
- << "Failed to create TCP ipv6 socket";
- gpr_log(GPR_DEBUG, "Opened fd: %d", s);
- ASSERT_TRUE(bind(s, (const sockaddr*)&addr, sizeof(addr)) == 0)
- << "Failed to bind socket " + std::to_string(s) +
- " to [::1]:" + std::to_string(dummy_port) +
- ". errno: " + std::to_string(errno);
- ASSERT_TRUE(listen(s, 1) == 0) << "Failed to listen on socket " +
- std::to_string(s) +
- ". errno: " + std::to_string(errno);
- sockets.push_back(s);
- }
- // Do a non-blocking accept followed by a close on all of those sockets.
- // Do this in a separate loop to try to induce a time window to hit races.
- for (size_t i = 0; i < sockets.size(); i++) {
- gpr_log(GPR_DEBUG, "non-blocking accept then close on %d", sockets[i]);
- if (accept(sockets[i], nullptr, nullptr)) {
- // If e.g. a "shutdown" was called on this fd from another thread,
- // then this accept call should fail with an unexpected error.
- ASSERT_TRUE(errno == EAGAIN || errno == EWOULDBLOCK)
- << "OpenAndCloseSocketsStressLoop accept on socket " +
- std::to_string(sockets[i]) +
- " failed in "
- "an unexpected way. "
- "errno: " +
- std::to_string(errno) +
- ". Socket use-after-close bugs are likely.";
- }
- ASSERT_TRUE(close(sockets[i]) == 0)
- << "Failed to close socket: " + std::to_string(sockets[i]) +
- ". errno: " + std::to_string(errno);
- }
- }
-}
-
void CheckResolverResultLocked(void* argsp, grpc_error* err) {
- EXPECT_EQ(err, GRPC_ERROR_NONE);
ArgsStruct* args = (ArgsStruct*)argsp;
grpc_channel_args* channel_args = args->channel_args;
const grpc_arg* channel_arg =
@@ -347,17 +271,7 @@ void CheckResolverResultLocked(void* argsp, grpc_error* err) {
gpr_mu_unlock(args->mu);
}
-void CheckResolvedWithoutErrorLocked(void* argsp, grpc_error* err) {
- EXPECT_EQ(err, GRPC_ERROR_NONE);
- ArgsStruct* args = (ArgsStruct*)argsp;
- gpr_atm_rel_store(&args->done_atm, 1);
- gpr_mu_lock(args->mu);
- GRPC_LOG_IF_ERROR("pollset_kick", grpc_pollset_kick(args->pollset, nullptr));
- gpr_mu_unlock(args->mu);
-}
-
-void RunResolvesRelevantRecordsTest(void (*OnDoneLocked)(void* arg,
- grpc_error* error)) {
+TEST(ResolverComponentTest, TestResolvesRelevantRecords) {
grpc_core::ExecCtx exec_ctx;
ArgsStruct args;
ArgsInit(&args);
@@ -375,32 +289,14 @@ void RunResolvesRelevantRecordsTest(void (*OnDoneLocked)(void* arg,
args.pollset_set, args.lock);
gpr_free(whole_uri);
grpc_closure on_resolver_result_changed;
- GRPC_CLOSURE_INIT(&on_resolver_result_changed, OnDoneLocked, (void*)&args,
- grpc_combiner_scheduler(args.lock));
+ GRPC_CLOSURE_INIT(&on_resolver_result_changed, CheckResolverResultLocked,
+ (void*)&args, grpc_combiner_scheduler(args.lock));
resolver->NextLocked(&args.channel_args, &on_resolver_result_changed);
grpc_core::ExecCtx::Get()->Flush();
PollPollsetUntilRequestDone(&args);
ArgsFinish(&args);
}
-TEST(ResolverComponentTest, TestResolvesRelevantRecords) {
- RunResolvesRelevantRecordsTest(CheckResolverResultLocked);
-}
-
-TEST(ResolverComponentTest, TestResolvesRelevantRecordsWithConcurrentFdStress) {
- // Start up background stress thread
- int dummy_port = grpc_pick_unused_port_or_die();
- gpr_event done_ev;
- gpr_event_init(&done_ev);
- std::thread socket_stress_thread(OpenAndCloseSocketsStressLoop, dummy_port,
- &done_ev);
- // Run the resolver test
- RunResolvesRelevantRecordsTest(CheckResolvedWithoutErrorLocked);
- // Shutdown and join stress thread
- gpr_event_set(&done_ev, (void*)1);
- socket_stress_thread.join();
-}
-
} // namespace
int main(int argc, char** argv) {