aboutsummaryrefslogtreecommitdiffhomepage
path: root/test/cpp
diff options
context:
space:
mode:
Diffstat (limited to 'test/cpp')
-rw-r--r--test/cpp/interop/interop_server.cc22
-rw-r--r--test/cpp/interop/server_helper.h24
-rw-r--r--test/cpp/microbenchmarks/BUILD6
-rw-r--r--test/cpp/microbenchmarks/bm_arena.cc16
-rw-r--r--test/cpp/microbenchmarks/bm_call_create.cc14
-rw-r--r--test/cpp/microbenchmarks/bm_chttp2_hpack.cc14
-rw-r--r--test/cpp/microbenchmarks/bm_chttp2_transport.cc16
-rw-r--r--test/cpp/microbenchmarks/bm_closure.cc14
-rw-r--r--test/cpp/microbenchmarks/bm_cq.cc14
-rw-r--r--test/cpp/microbenchmarks/bm_cq_multiple_threads.cc14
-rw-r--r--test/cpp/microbenchmarks/bm_error.cc14
-rw-r--r--test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc14
-rw-r--r--test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc14
-rw-r--r--test/cpp/microbenchmarks/bm_fullstack_trickle.cc8
-rw-r--r--test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc14
-rw-r--r--test/cpp/microbenchmarks/bm_metadata.cc14
-rw-r--r--test/cpp/microbenchmarks/bm_pollset.cc16
-rw-r--r--test/cpp/microbenchmarks/helpers.cc14
-rw-r--r--test/cpp/naming/BUILD7
-rw-r--r--test/cpp/naming/address_sorting_test.cc23
-rwxr-xr-xtest/cpp/naming/gen_build_yaml.py17
-rwxr-xr-xtest/cpp/naming/generate_resolver_component_tests.bzl2
-rwxr-xr-xtest/cpp/naming/resolver_component_tests_runner.py275
-rwxr-xr-xtest/cpp/naming/resolver_component_tests_runner.sh187
-rw-r--r--test/cpp/naming/resolver_component_tests_runner_invoker.cc2
-rwxr-xr-xtest/cpp/naming/utils/dns_resolver.py6
-rwxr-xr-xtest/cpp/naming/utils/dns_server.py21
-rwxr-xr-xtest/cpp/naming/utils/tcp_connect.py6
-rwxr-xr-xtest/cpp/qps/gen_build_yaml.py7
-rw-r--r--test/cpp/server/BUILD13
-rw-r--r--test/cpp/server/load_reporter/BUILD31
-rw-r--r--test/cpp/server/load_reporter/load_data_store_test.cc481
-rw-r--r--test/cpp/server/server_builder_with_socket_mutator_test.cc116
33 files changed, 1219 insertions, 237 deletions
diff --git a/test/cpp/interop/interop_server.cc b/test/cpp/interop/interop_server.cc
index 6526e0535b..f55d624b21 100644
--- a/test/cpp/interop/interop_server.cc
+++ b/test/cpp/interop/interop_server.cc
@@ -318,12 +318,27 @@ class TestServiceImpl : public TestService::Service {
void grpc::testing::interop::RunServer(
std::shared_ptr<ServerCredentials> creds) {
- RunServer(creds, FLAGS_port, nullptr);
+ RunServer(creds, FLAGS_port, nullptr, nullptr);
+}
+
+void grpc::testing::interop::RunServer(
+ std::shared_ptr<ServerCredentials> creds,
+ std::unique_ptr<std::vector<std::unique_ptr<ServerBuilderOption>>>
+ server_options) {
+ RunServer(creds, FLAGS_port, nullptr, std::move(server_options));
}
void grpc::testing::interop::RunServer(
std::shared_ptr<ServerCredentials> creds, const int port,
ServerStartedCondition* server_started_condition) {
+ RunServer(creds, port, server_started_condition, nullptr);
+}
+
+void grpc::testing::interop::RunServer(
+ std::shared_ptr<ServerCredentials> creds, const int port,
+ ServerStartedCondition* server_started_condition,
+ std::unique_ptr<std::vector<std::unique_ptr<ServerBuilderOption>>>
+ server_options) {
GPR_ASSERT(port != 0);
std::ostringstream server_address;
server_address << "0.0.0.0:" << port;
@@ -335,6 +350,11 @@ void grpc::testing::interop::RunServer(
ServerBuilder builder;
builder.RegisterService(&service);
builder.AddListeningPort(server_address.str(), creds);
+ if (server_options != nullptr) {
+ for (size_t i = 0; i < server_options->size(); i++) {
+ builder.SetOption(std::move((*server_options)[i]));
+ }
+ }
if (FLAGS_max_send_message_size >= 0) {
builder.SetMaxSendMessageSize(FLAGS_max_send_message_size);
}
diff --git a/test/cpp/interop/server_helper.h b/test/cpp/interop/server_helper.h
index 3004e7ff81..265874df70 100644
--- a/test/cpp/interop/server_helper.h
+++ b/test/cpp/interop/server_helper.h
@@ -26,6 +26,8 @@
#include <grpc/impl/codegen/atm.h>
#include <grpcpp/security/server_credentials.h>
+#include <grpcpp/server.h>
+#include <grpcpp/server_builder.h>
#include <grpcpp/server_context.h>
namespace grpc {
@@ -72,6 +74,28 @@ void RunServer(std::shared_ptr<ServerCredentials> creds);
void RunServer(std::shared_ptr<ServerCredentials> creds, int port,
ServerStartedCondition* server_started_condition);
+/// Run gRPC interop server.
+///
+/// \param creds The credentials associated with the server.
+/// \param server_options List of options to set when building the server.
+void RunServer(
+ std::shared_ptr<ServerCredentials> creds,
+ std::unique_ptr<std::vector<std::unique_ptr<ServerBuilderOption>>>
+ server_options);
+
+/// Run gRPC interop server.
+///
+/// \param creds The credentials associated with the server.
+/// \param port Port to use for the server.
+/// \param server_options List of options to set when building the server.
+/// \param server_started_condition (optional) Struct holding mutex, condition
+// variable, and condition used to notify when the server has started.
+void RunServer(
+ std::shared_ptr<ServerCredentials> creds, const int port,
+ ServerStartedCondition* server_started_condition,
+ std::unique_ptr<std::vector<std::unique_ptr<grpc::ServerBuilderOption>>>
+ server_options);
+
} // namespace interop
} // namespace testing
} // namespace grpc
diff --git a/test/cpp/microbenchmarks/BUILD b/test/cpp/microbenchmarks/BUILD
index 67f7e440b0..5dcfd94ed3 100644
--- a/test/cpp/microbenchmarks/BUILD
+++ b/test/cpp/microbenchmarks/BUILD
@@ -42,6 +42,7 @@ grpc_cc_library(
"//:grpc++_unsecure",
"//src/proto/grpc/testing:echo_proto",
"//test/core/util:grpc_test_util_unsecure",
+ "//test/cpp/util:test_config",
],
)
@@ -113,10 +114,7 @@ grpc_cc_binary(
name = "bm_fullstack_trickle",
testonly = 1,
srcs = ["bm_fullstack_trickle.cc"],
- deps = [
- ":helpers",
- "//test/cpp/util:test_config",
- ],
+ deps = [":helpers"],
)
grpc_cc_library(
diff --git a/test/cpp/microbenchmarks/bm_arena.cc b/test/cpp/microbenchmarks/bm_arena.cc
index 69c8c1c029..b97c954fae 100644
--- a/test/cpp/microbenchmarks/bm_arena.cc
+++ b/test/cpp/microbenchmarks/bm_arena.cc
@@ -18,9 +18,10 @@
/* Benchmark arenas */
+#include <benchmark/benchmark.h>
#include "src/core/lib/gpr/arena.h"
#include "test/cpp/microbenchmarks/helpers.h"
-#include "third_party/benchmark/include/benchmark/benchmark.h"
+#include "test/cpp/util/test_config.h"
static void BM_Arena_NoOp(benchmark::State& state) {
while (state.KeepRunning()) {
@@ -56,4 +57,15 @@ static void BM_Arena_Batch(benchmark::State& state) {
}
BENCHMARK(BM_Arena_Batch)->Ranges({{1, 64 * 1024}, {1, 64}, {1, 1024}});
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_call_create.cc b/test/cpp/microbenchmarks/bm_call_create.cc
index 85a9f5e137..831b29c506 100644
--- a/test/cpp/microbenchmarks/bm_call_create.cc
+++ b/test/cpp/microbenchmarks/bm_call_create.cc
@@ -46,6 +46,7 @@
#include "src/cpp/client/create_channel_internal.h"
#include "src/proto/grpc/testing/echo.grpc.pb.h"
#include "test/cpp/microbenchmarks/helpers.h"
+#include "test/cpp/util/test_config.h"
auto& force_library_initialization = Library::get();
@@ -813,4 +814,15 @@ static void BM_IsolatedCall_StreamingSend(benchmark::State& state) {
}
BENCHMARK(BM_IsolatedCall_StreamingSend);
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc
index d0f3ec8e8b..823c76f755 100644
--- a/test/cpp/microbenchmarks/bm_chttp2_hpack.cc
+++ b/test/cpp/microbenchmarks/bm_chttp2_hpack.cc
@@ -33,6 +33,7 @@
#include "src/core/lib/transport/timeout_encoding.h"
#include "test/cpp/microbenchmarks/helpers.h"
+#include "test/cpp/util/test_config.h"
auto& force_library_initialization = Library::get();
@@ -855,4 +856,15 @@ BENCHMARK_TEMPLATE(BM_HpackParserParseHeader, SameDeadline, OnHeaderNew);
} // namespace hpack_parser_fixtures
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_chttp2_transport.cc b/test/cpp/microbenchmarks/bm_chttp2_transport.cc
index d00c79b610..1e9bd273aa 100644
--- a/test/cpp/microbenchmarks/bm_chttp2_transport.cc
+++ b/test/cpp/microbenchmarks/bm_chttp2_transport.cc
@@ -18,6 +18,7 @@
/* Microbenchmarks around CHTTP2 transport operations */
+#include <benchmark/benchmark.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include <grpc/support/string_util.h>
@@ -33,7 +34,7 @@
#include "src/core/lib/slice/slice_internal.h"
#include "src/core/lib/transport/static_metadata.h"
#include "test/cpp/microbenchmarks/helpers.h"
-#include "third_party/benchmark/include/benchmark/benchmark.h"
+#include "test/cpp/util/test_config.h"
auto& force_library_initialization = Library::get();
@@ -638,4 +639,15 @@ static void BM_TransportStreamRecv(benchmark::State& state) {
}
BENCHMARK(BM_TransportStreamRecv)->Range(0, 128 * 1024 * 1024);
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_closure.cc b/test/cpp/microbenchmarks/bm_closure.cc
index 6d88faecc0..8bdc3b9385 100644
--- a/test/cpp/microbenchmarks/bm_closure.cc
+++ b/test/cpp/microbenchmarks/bm_closure.cc
@@ -28,6 +28,7 @@
#include "src/core/lib/iomgr/exec_ctx.h"
#include "test/cpp/microbenchmarks/helpers.h"
+#include "test/cpp/util/test_config.h"
auto& force_library_initialization = Library::get();
@@ -415,4 +416,15 @@ static void BM_ClosureReschedOnCombinerFinally(benchmark::State& state) {
}
BENCHMARK(BM_ClosureReschedOnCombinerFinally);
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_cq.cc b/test/cpp/microbenchmarks/bm_cq.cc
index 342a95ed10..a7cb939265 100644
--- a/test/cpp/microbenchmarks/bm_cq.cc
+++ b/test/cpp/microbenchmarks/bm_cq.cc
@@ -25,6 +25,7 @@
#include <grpcpp/completion_queue.h>
#include <grpcpp/impl/grpc_library.h>
#include "test/cpp/microbenchmarks/helpers.h"
+#include "test/cpp/util/test_config.h"
#include "src/core/lib/surface/completion_queue.h"
@@ -148,4 +149,15 @@ BENCHMARK(BM_EmptyCore);
} // namespace testing
} // namespace grpc
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc
index ec79b95cd8..da095c3e68 100644
--- a/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc
+++ b/test/cpp/microbenchmarks/bm_cq_multiple_threads.cc
@@ -24,6 +24,7 @@
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
#include "test/cpp/microbenchmarks/helpers.h"
+#include "test/cpp/util/test_config.h"
#include "src/core/lib/iomgr/ev_posix.h"
#include "src/core/lib/iomgr/port.h"
@@ -164,4 +165,15 @@ BENCHMARK(BM_Cq_Throughput)->ThreadRange(1, 16)->UseRealTime();
} // namespace testing
} // namespace grpc
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_error.cc b/test/cpp/microbenchmarks/bm_error.cc
index d12f475a49..ae557a580a 100644
--- a/test/cpp/microbenchmarks/bm_error.cc
+++ b/test/cpp/microbenchmarks/bm_error.cc
@@ -25,6 +25,7 @@
#include "src/core/lib/transport/error_utils.h"
#include "test/cpp/microbenchmarks/helpers.h"
+#include "test/cpp/util/test_config.h"
auto& force_library_initialization = Library::get();
@@ -310,4 +311,15 @@ BENCHMARK_SUITE(ErrorWithGrpcStatus);
BENCHMARK_SUITE(ErrorWithHttpError);
BENCHMARK_SUITE(ErrorWithNestedGrpcStatus);
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc b/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc
index 655e032faf..34df77aca3 100644
--- a/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc
+++ b/test/cpp/microbenchmarks/bm_fullstack_streaming_ping_pong.cc
@@ -19,6 +19,7 @@
/* Benchmark gRPC end2end in various configurations */
#include "test/cpp/microbenchmarks/fullstack_streaming_ping_pong.h"
+#include "test/cpp/util/test_config.h"
namespace grpc {
namespace testing {
@@ -114,4 +115,15 @@ BENCHMARK_TEMPLATE(BM_StreamingPingPongWithCoalescingApi, MinInProcess,
} // namespace testing
} // namespace grpc
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc b/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc
index c7ceacd320..da98f3cbcd 100644
--- a/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc
+++ b/test/cpp/microbenchmarks/bm_fullstack_streaming_pump.cc
@@ -19,6 +19,7 @@
/* Benchmark gRPC end2end in various configurations */
#include "test/cpp/microbenchmarks/fullstack_streaming_pump.h"
+#include "test/cpp/util/test_config.h"
namespace grpc {
namespace testing {
@@ -64,4 +65,15 @@ BENCHMARK_TEMPLATE(BM_PumpStreamServerToClient, MinInProcessCHTTP2)->Arg(0);
} // namespace testing
} // namespace grpc
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc
index 3b21c4c278..1af92d2c80 100644
--- a/test/cpp/microbenchmarks/bm_fullstack_trickle.cc
+++ b/test/cpp/microbenchmarks/bm_fullstack_trickle.cc
@@ -458,10 +458,16 @@ BENCHMARK(BM_PumpUnbalancedUnary_Trickle)->Apply(UnaryTrickleArgs);
extern gpr_timespec (*gpr_now_impl)(gpr_clock_type clock_type);
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
int main(int argc, char** argv) {
::benchmark::Initialize(&argc, argv);
::grpc::testing::InitTest(&argc, &argv, false);
grpc_timer_manager_set_threading(false);
gpr_now_impl = ::grpc::testing::fake_now;
- ::benchmark::RunSpecifiedBenchmarks();
+ benchmark::RunTheBenchmarksNamespaced();
}
diff --git a/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc
index fa41d114c0..5a7a8d5baf 100644
--- a/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc
+++ b/test/cpp/microbenchmarks/bm_fullstack_unary_ping_pong.cc
@@ -19,6 +19,7 @@
/* Benchmark gRPC end2end in various configurations */
#include "test/cpp/microbenchmarks/fullstack_unary_ping_pong.h"
+#include "test/cpp/util/test_config.h"
namespace grpc {
namespace testing {
@@ -164,4 +165,15 @@ BENCHMARK_TEMPLATE(BM_UnaryPingPong, InProcess, NoOpMutator,
} // namespace testing
} // namespace grpc
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_metadata.cc b/test/cpp/microbenchmarks/bm_metadata.cc
index f1e7890fc0..553b33c402 100644
--- a/test/cpp/microbenchmarks/bm_metadata.cc
+++ b/test/cpp/microbenchmarks/bm_metadata.cc
@@ -25,6 +25,7 @@
#include "src/core/lib/transport/static_metadata.h"
#include "test/cpp/microbenchmarks/helpers.h"
+#include "test/cpp/util/test_config.h"
auto& force_library_initialization = Library::get();
@@ -290,4 +291,15 @@ static void BM_MetadataRefUnrefStatic(benchmark::State& state) {
}
BENCHMARK(BM_MetadataRefUnrefStatic);
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/bm_pollset.cc b/test/cpp/microbenchmarks/bm_pollset.cc
index f49f6671ae..bcb68ff229 100644
--- a/test/cpp/microbenchmarks/bm_pollset.cc
+++ b/test/cpp/microbenchmarks/bm_pollset.cc
@@ -18,6 +18,7 @@
/* Test out pollset latencies */
+#include <benchmark/benchmark.h>
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
#include <grpc/support/log.h>
@@ -29,7 +30,7 @@
#include "src/core/lib/iomgr/wakeup_fd_posix.h"
#include "test/cpp/microbenchmarks/helpers.h"
-#include "third_party/benchmark/include/benchmark/benchmark.h"
+#include "test/cpp/util/test_config.h"
#include <string.h>
@@ -256,4 +257,15 @@ static void BM_SingleThreadPollOneFd(benchmark::State& state) {
}
BENCHMARK(BM_SingleThreadPollOneFd);
-BENCHMARK_MAIN();
+// Some distros have RunSpecifiedBenchmarks under the benchmark namespace,
+// and others do not. This allows us to support both modes.
+namespace benchmark {
+void RunTheBenchmarksNamespaced() { RunSpecifiedBenchmarks(); }
+} // namespace benchmark
+
+int main(int argc, char** argv) {
+ ::benchmark::Initialize(&argc, argv);
+ ::grpc::testing::InitTest(&argc, &argv, false);
+ benchmark::RunTheBenchmarksNamespaced();
+ return 0;
+}
diff --git a/test/cpp/microbenchmarks/helpers.cc b/test/cpp/microbenchmarks/helpers.cc
index e4a31f50a9..e4ba37e2d6 100644
--- a/test/cpp/microbenchmarks/helpers.cc
+++ b/test/cpp/microbenchmarks/helpers.cc
@@ -48,16 +48,10 @@ void TrackCounters::AddToLabel(std::ostream& out, benchmark::State& state) {
static_cast<double>(state.iterations()));
}
for (int i = 0; i < GRPC_STATS_HISTOGRAM_COUNT; i++) {
- std::ostringstream median_ss;
- median_ss << grpc_stats_histogram_name[i] << "-median";
- state.counters[median_ss.str()] =
- benchmark::Counter(grpc_stats_histo_percentile(
- &stats, static_cast<grpc_stats_histograms>(i), 50.0));
- std::ostringstream tail_ss;
- tail_ss << grpc_stats_histogram_name[i] << "-99p";
- state.counters[tail_ss.str()] =
- benchmark::Counter(grpc_stats_histo_percentile(
- &stats, static_cast<grpc_stats_histograms>(i), 99.0));
+ out << " " << grpc_stats_histogram_name[i] << "-median:"
+ << grpc_stats_histo_percentile(&stats, (grpc_stats_histograms)i, 50.0)
+ << " " << grpc_stats_histogram_name[i] << "-99p:"
+ << grpc_stats_histo_percentile(&stats, (grpc_stats_histograms)i, 99.0);
}
#ifdef GPR_LOW_LEVEL_COUNTERS
grpc_memory_counters counters_at_end = grpc_memory_counters_snapshot();
diff --git a/test/cpp/naming/BUILD b/test/cpp/naming/BUILD
index 54b53d2792..fa0b216f8f 100644
--- a/test/cpp/naming/BUILD
+++ b/test/cpp/naming/BUILD
@@ -22,16 +22,17 @@ package(
licenses(["notice"]) # Apache v2
-load("//bazel:grpc_build_system.bzl", "grpc_sh_binary", "grpc_py_binary")
+load("//bazel:grpc_build_system.bzl", "grpc_py_binary")
load(":generate_resolver_component_tests.bzl", "generate_resolver_component_tests")
# Meant to be invoked only through the top-level shell script driver.
-grpc_sh_binary(
+grpc_py_binary(
name = "resolver_component_tests_runner",
srcs = [
- "resolver_component_tests_runner.sh",
+ "resolver_component_tests_runner.py",
],
+ testonly = True,
)
generate_resolver_component_tests()
diff --git a/test/cpp/naming/address_sorting_test.cc b/test/cpp/naming/address_sorting_test.cc
index a423733caf..a92e9e3b3e 100644
--- a/test/cpp/naming/address_sorting_test.cc
+++ b/test/cpp/naming/address_sorting_test.cc
@@ -298,6 +298,29 @@ TEST(AddressSortingTest, TestUsesLabelFromDefaultTable) {
});
}
+/* Flip the input on the test above to reorder the sort function's
+ * comparator's inputs. */
+TEST(AddressSortingTest, TestUsesLabelFromDefaultTableInputFlipped) {
+ bool ipv4_supported = true;
+ bool ipv6_supported = true;
+ OverrideAddressSortingSourceAddrFactory(
+ ipv4_supported, ipv6_supported,
+ {
+ {"[2002::5001]:443", {"[2001::5002]:0", AF_INET6}},
+ {"[2001::5001]:443",
+ {"[2001::5002]:0", AF_INET6}}, // matching labels
+ });
+ grpc_lb_addresses* lb_addrs = BuildLbAddrInputs({
+ {"[2001::5001]:443", AF_INET6},
+ {"[2002::5001]:443", AF_INET6},
+ });
+ grpc_cares_wrapper_test_only_address_sorting_sort(lb_addrs);
+ VerifyLbAddrOutputs(lb_addrs, {
+ "[2001::5001]:443",
+ "[2002::5001]:443",
+ });
+}
+
/* Tests for rule 6 */
TEST(AddressSortingTest,
diff --git a/test/cpp/naming/gen_build_yaml.py b/test/cpp/naming/gen_build_yaml.py
index adebc62084..493713ff0e 100755
--- a/test/cpp/naming/gen_build_yaml.py
+++ b/test/cpp/naming/gen_build_yaml.py
@@ -119,12 +119,19 @@ def _resolver_test_cases(resolver_component_data, records_to_skip):
for test_case in resolver_component_data['resolver_component_tests']:
if test_case['record_to_resolve'] in records_to_skip:
continue
+ target_name = _append_zone_name(
+ test_case['record_to_resolve'],
+ resolver_component_data['resolver_tests_common_zone_name'])
out.append({
- 'target_name': _append_zone_name(test_case['record_to_resolve'],
- resolver_component_data['resolver_tests_common_zone_name']),
- 'expected_addrs': _build_expected_addrs_cmd_arg(test_case['expected_addrs']),
- 'expected_chosen_service_config': (test_case['expected_chosen_service_config'] or ''),
- 'expected_lb_policy': (test_case['expected_lb_policy'] or ''),
+ 'test_title': target_name,
+ 'arg_names_and_values': [
+ ('target_name', target_name),
+ ('expected_addrs',
+ _build_expected_addrs_cmd_arg(test_case['expected_addrs'])),
+ ('expected_chosen_service_config',
+ (test_case['expected_chosen_service_config'] or '')),
+ ('expected_lb_policy', (test_case['expected_lb_policy'] or '')),
+ ],
})
return out
diff --git a/test/cpp/naming/generate_resolver_component_tests.bzl b/test/cpp/naming/generate_resolver_component_tests.bzl
index ebc167931d..5e9aa63abe 100755
--- a/test/cpp/naming/generate_resolver_component_tests.bzl
+++ b/test/cpp/naming/generate_resolver_component_tests.bzl
@@ -13,7 +13,7 @@
# See the License for the specific language governing permissions and
# limitations under the License.
-load("//bazel:grpc_build_system.bzl", "grpc_sh_binary", "grpc_cc_test", "grpc_cc_binary")
+load("//bazel:grpc_build_system.bzl", "grpc_cc_test", "grpc_cc_binary")
def generate_resolver_component_tests():
for unsecure_build_config_suffix in ['_unsecure', '']:
diff --git a/test/cpp/naming/resolver_component_tests_runner.py b/test/cpp/naming/resolver_component_tests_runner.py
new file mode 100755
index 0000000000..69386ebeb0
--- /dev/null
+++ b/test/cpp/naming/resolver_component_tests_runner.py
@@ -0,0 +1,275 @@
+#!/usr/bin/env python
+# Copyright 2015 gRPC authors.
+#
+# 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.
+
+# This file is auto-generated
+
+import argparse
+import sys
+import subprocess
+import tempfile
+import os
+import time
+import signal
+
+
+argp = argparse.ArgumentParser(description='Run c-ares resolver tests')
+argp.add_argument('--test_bin_path', default=None, type=str,
+ help='Path to gtest test binary to invoke.')
+argp.add_argument('--dns_server_bin_path', default=None, type=str,
+ help='Path to local DNS server python script.')
+argp.add_argument('--records_config_path', default=None, type=str,
+ help=('Path to DNS records yaml file that '
+ 'specifies records for the DNS sever. '))
+argp.add_argument('--dns_server_port', default=None, type=int,
+ help=('Port that local DNS server is listening on.'))
+argp.add_argument('--dns_resolver_bin_path', default=None, type=str,
+ help=('Path to the DNS health check utility.'))
+argp.add_argument('--tcp_connect_bin_path', default=None, type=str,
+ help=('Path to the TCP health check utility.'))
+args = argp.parse_args()
+
+def test_runner_log(msg):
+ sys.stderr.write('\n%s: %s\n' % (__file__, msg))
+
+cur_resolver = os.environ.get('GRPC_DNS_RESOLVER')
+if cur_resolver and cur_resolver != 'ares':
+ test_runner_log(('WARNING: cur resolver set to %s. This set of tests '
+ 'needs to use GRPC_DNS_RESOLVER=ares.'))
+ test_runner_log('Exit 1 without running tests.')
+ sys.exit(1)
+os.environ.update({'GRPC_DNS_RESOLVER': 'ares'})
+
+def wait_until_dns_server_is_up(args,
+ dns_server_subprocess,
+ dns_server_subprocess_output):
+ for i in range(0, 30):
+ test_runner_log('Health check: attempt to connect to DNS server over TCP.')
+ tcp_connect_subprocess = subprocess.Popen([
+ args.tcp_connect_bin_path,
+ '--server_host', '127.0.0.1',
+ '--server_port', str(args.dns_server_port),
+ '--timeout', str(1)])
+ tcp_connect_subprocess.communicate()
+ if tcp_connect_subprocess.returncode == 0:
+ test_runner_log(('Health check: attempt to make an A-record '
+ 'query to DNS server.'))
+ dns_resolver_subprocess = subprocess.Popen([
+ args.dns_resolver_bin_path,
+ '--qname', 'health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp',
+ '--server_host', '127.0.0.1',
+ '--server_port', str(args.dns_server_port)],
+ stdout=subprocess.PIPE)
+ dns_resolver_stdout, _ = dns_resolver_subprocess.communicate()
+ if dns_resolver_subprocess.returncode == 0:
+ if '123.123.123.123' in dns_resolver_stdout:
+ test_runner_log(('DNS server is up! '
+ 'Successfully reached it over UDP and TCP.'))
+ return
+ time.sleep(0.1)
+ dns_server_subprocess.kill()
+ dns_server_subprocess.wait()
+ test_runner_log(('Failed to reach DNS server over TCP and/or UDP. '
+ 'Exitting without running tests.'))
+ test_runner_log('======= DNS server stdout '
+ '(merged stdout and stderr) =============')
+ with open(dns_server_subprocess_output, 'r') as l:
+ test_runner_log(l.read())
+ test_runner_log('======= end DNS server output=========')
+ sys.exit(1)
+
+dns_server_subprocess_output = tempfile.mktemp()
+with open(dns_server_subprocess_output, 'w') as l:
+ dns_server_subprocess = subprocess.Popen([
+ args.dns_server_bin_path,
+ '--port', str(args.dns_server_port),
+ '--records_config_path', args.records_config_path],
+ stdin=subprocess.PIPE,
+ stdout=l,
+ stderr=l)
+
+def _quit_on_signal(signum, _frame):
+ test_runner_log('Received signal: %d' % signum)
+ dns_server_subprocess.kill()
+ dns_server_subprocess.wait()
+ sys.exit(1)
+
+signal.signal(signal.SIGINT, _quit_on_signal)
+signal.signal(signal.SIGTERM, _quit_on_signal)
+wait_until_dns_server_is_up(args,
+ dns_server_subprocess,
+ dns_server_subprocess_output)
+num_test_failures = 0
+
+test_runner_log('Run test with target: %s' % 'srv-ipv4-single-target.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'srv-ipv4-single-target.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '1.2.3.4:1234,True',
+ '--expected_chosen_service_config', '',
+ '--expected_lb_policy', '',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'srv-ipv4-multi-target.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'srv-ipv4-multi-target.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '1.2.3.5:1234,True;1.2.3.6:1234,True;1.2.3.7:1234,True',
+ '--expected_chosen_service_config', '',
+ '--expected_lb_policy', '',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'srv-ipv6-single-target.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'srv-ipv6-single-target.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '[2607:f8b0:400a:801::1001]:1234,True',
+ '--expected_chosen_service_config', '',
+ '--expected_lb_policy', '',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'srv-ipv6-multi-target.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'srv-ipv6-multi-target.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '[2607:f8b0:400a:801::1002]:1234,True;[2607:f8b0:400a:801::1003]:1234,True;[2607:f8b0:400a:801::1004]:1234,True',
+ '--expected_chosen_service_config', '',
+ '--expected_lb_policy', '',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'srv-ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'srv-ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '1.2.3.4:1234,True',
+ '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}',
+ '--expected_lb_policy', 'round_robin',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'ipv4-no-srv-simple-service-config.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'ipv4-no-srv-simple-service-config.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '1.2.3.4:443,False',
+ '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService","waitForReady":true}]}]}',
+ '--expected_lb_policy', 'round_robin',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'ipv4-no-config-for-cpp.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'ipv4-no-config-for-cpp.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '1.2.3.4:443,False',
+ '--expected_chosen_service_config', '',
+ '--expected_lb_policy', '',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'ipv4-cpp-config-has-zero-percentage.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'ipv4-cpp-config-has-zero-percentage.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '1.2.3.4:443,False',
+ '--expected_chosen_service_config', '',
+ '--expected_lb_policy', '',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'ipv4-second-language-is-cpp.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'ipv4-second-language-is-cpp.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '1.2.3.4:443,False',
+ '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}',
+ '--expected_lb_policy', 'round_robin',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'ipv4-config-with-percentages.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'ipv4-config-with-percentages.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '1.2.3.4:443,False',
+ '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService","waitForReady":true}]}]}',
+ '--expected_lb_policy', 'round_robin',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '1.2.3.4:1234,True;1.2.3.4:443,False',
+ '--expected_chosen_service_config', '',
+ '--expected_lb_policy', '',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '[2607:f8b0:400a:801::1002]:1234,True;[2607:f8b0:400a:801::1002]:443,False',
+ '--expected_chosen_service_config', '',
+ '--expected_lb_policy', '',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('Run test with target: %s' % 'ipv4-config-causing-fallback-to-tcp.resolver-tests-version-4.grpctestingexp.')
+current_test_subprocess = subprocess.Popen([
+ args.test_bin_path,
+ '--target_name', 'ipv4-config-causing-fallback-to-tcp.resolver-tests-version-4.grpctestingexp.',
+ '--expected_addrs', '1.2.3.4:443,False',
+ '--expected_chosen_service_config', '{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooThree","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFour","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFive","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSix","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSeven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEight","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooNine","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTen","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEleven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]}]}',
+ '--expected_lb_policy', '',
+ '--local_dns_server_address', '127.0.0.1:%d' % args.dns_server_port])
+current_test_subprocess.communicate()
+if current_test_subprocess.returncode != 0:
+ num_test_failures += 1
+
+test_runner_log('now kill DNS server')
+dns_server_subprocess.kill()
+dns_server_subprocess.wait()
+test_runner_log('%d tests failed.' % num_test_failures)
+sys.exit(num_test_failures)
diff --git a/test/cpp/naming/resolver_component_tests_runner.sh b/test/cpp/naming/resolver_component_tests_runner.sh
deleted file mode 100755
index 3f8765fa94..0000000000
--- a/test/cpp/naming/resolver_component_tests_runner.sh
+++ /dev/null
@@ -1,187 +0,0 @@
-#!/bin/bash
-# Copyright 2015 gRPC authors.
-#
-# 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.
-
-# This file is auto-generated
-
-set -ex
-
-# all command args required in this set order
-FLAGS_test_bin_path=$(echo "$1" | grep '\--test_bin_path=' | sed 's/^--test_bin_path=//')
-FLAGS_dns_server_bin_path=$(echo "$2" | grep '\--dns_server_bin_path=' | sed 's/^--dns_server_bin_path=//')
-FLAGS_records_config_path=$(echo "$3" | grep '\--records_config_path=' | sed 's/^--records_config_path=//')
-FLAGS_dns_server_port=$(echo "$4" | grep '\--dns_server_port=' | sed 's/^--dns_server_port=//')
-FLAGS_dns_resolver_bin_path=$(echo "$5" | grep '\--dns_resolver_bin_path=' | sed 's/^--dns_resolver_bin_path=//')
-FLAGS_tcp_connect_bin_path=$(echo "$6" | grep '\--tcp_connect_bin_path=' | sed 's/^--tcp_connect_bin_path=//')
-
-for cmd_arg in "$FLAGS_test_bin_path" "$FLAGS_dns_server_bin_path" "$FLAGS_records_config_path" "$FLAGS_dns_server_port" "$FLAGS_dns_resolver_bin_path" "$FLAGS_tcp_connect_bin_path"; do
- if [[ "$cmd_arg" == "" ]]; then
- echo "Missing a CMD arg" && exit 1
- fi
-done
-
-if [[ "$GRPC_DNS_RESOLVER" != "" && "$GRPC_DNS_RESOLVER" != ares ]]; then
- echo "This test only works under GRPC_DNS_RESOLVER=ares. Have GRPC_DNS_RESOLVER=$GRPC_DNS_RESOLVER" && exit 1
-fi
-export GRPC_DNS_RESOLVER=ares
-
-DNS_SERVER_LOG="$(mktemp)"
-"$FLAGS_dns_server_bin_path" --records_config_path="$FLAGS_records_config_path" --port="$FLAGS_dns_server_port" > "$DNS_SERVER_LOG" 2>&1 &
-DNS_SERVER_PID=$!
-echo "Local DNS server started. PID: $DNS_SERVER_PID"
-
-# Health check local DNS server TCP and UDP ports
-for ((i=0;i<30;i++));
-do
- echo "Retry health-check local DNS server by attempting a DNS query and TCP handshake"
- RETRY=0
- $FLAGS_dns_resolver_bin_path -s 127.0.0.1 -p "$FLAGS_dns_server_port" -n health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp. -t 1 | grep '123.123.123.123' || RETRY=1
- $FLAGS_tcp_connect_bin_path -s 127.0.0.1 -p "$FLAGS_dns_server_port" -t 1 || RETRY=1
- if [[ "$RETRY" == 0 ]]; then
- break
- fi;
- sleep 0.1
-done
-
-if [[ $RETRY == 1 ]]; then
- echo "FAILED TO START LOCAL DNS SERVER"
- kill -SIGTERM "$DNS_SERVER_PID" || true
- wait
- echo "========== DNS server log (merged stdout and stderr) ========="
- cat "$DNS_SERVER_LOG"
- echo "========== end DNS server log ================================"
- exit 1
-fi
-
-function terminate_all {
- echo "Received signal. Terminating $! and $DNS_SERVER_PID"
- kill -SIGTERM "$!" || true
- kill -SIGTERM "$DNS_SERVER_PID" || true
- wait
- exit 1
-}
-
-trap terminate_all SIGTERM SIGINT
-
-EXIT_CODE=0
-# TODO: this test should check for GCE residency and skip tests using _grpclb._tcp.* SRV records once GCE residency checks are made
-# in the resolver.
-
-$FLAGS_test_bin_path \
- --target_name='srv-ipv4-single-target.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='1.2.3.4:1234,True' \
- --expected_chosen_service_config='' \
- --expected_lb_policy='' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='srv-ipv4-multi-target.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='1.2.3.5:1234,True;1.2.3.6:1234,True;1.2.3.7:1234,True' \
- --expected_chosen_service_config='' \
- --expected_lb_policy='' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='srv-ipv6-single-target.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='[2607:f8b0:400a:801::1001]:1234,True' \
- --expected_chosen_service_config='' \
- --expected_lb_policy='' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='srv-ipv6-multi-target.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='[2607:f8b0:400a:801::1002]:1234,True;[2607:f8b0:400a:801::1003]:1234,True;[2607:f8b0:400a:801::1004]:1234,True' \
- --expected_chosen_service_config='' \
- --expected_lb_policy='' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='srv-ipv4-simple-service-config.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='1.2.3.4:1234,True' \
- --expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]}]}' \
- --expected_lb_policy='round_robin' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='ipv4-no-srv-simple-service-config.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='1.2.3.4:443,False' \
- --expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"NoSrvSimpleService","waitForReady":true}]}]}' \
- --expected_lb_policy='round_robin' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='ipv4-no-config-for-cpp.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='1.2.3.4:443,False' \
- --expected_chosen_service_config='' \
- --expected_lb_policy='' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='ipv4-cpp-config-has-zero-percentage.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='1.2.3.4:443,False' \
- --expected_chosen_service_config='' \
- --expected_lb_policy='' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='ipv4-second-language-is-cpp.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='1.2.3.4:443,False' \
- --expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"CppService","waitForReady":true}]}]}' \
- --expected_lb_policy='round_robin' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='ipv4-config-with-percentages.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='1.2.3.4:443,False' \
- --expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"AlwaysPickedService","waitForReady":true}]}]}' \
- --expected_lb_policy='round_robin' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='srv-ipv4-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='1.2.3.4:1234,True;1.2.3.4:443,False' \
- --expected_chosen_service_config='' \
- --expected_lb_policy='' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='srv-ipv6-target-has-backend-and-balancer.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='[2607:f8b0:400a:801::1002]:1234,True;[2607:f8b0:400a:801::1002]:443,False' \
- --expected_chosen_service_config='' \
- --expected_lb_policy='' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-$FLAGS_test_bin_path \
- --target_name='ipv4-config-causing-fallback-to-tcp.resolver-tests-version-4.grpctestingexp.' \
- --expected_addrs='1.2.3.4:443,False' \
- --expected_chosen_service_config='{"loadBalancingPolicy":"round_robin","methodConfig":[{"name":[{"method":"Foo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwo","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooThree","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFour","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooFive","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSix","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooSeven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEight","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooNine","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTen","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooEleven","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]},{"name":[{"method":"FooTwelve","service":"SimpleService","waitForReady":true}]}]}' \
- --expected_lb_policy='' \
- --local_dns_server_address="127.0.0.1:$FLAGS_dns_server_port" &
-wait "$!" || EXIT_CODE=1
-
-kill -SIGTERM "$DNS_SERVER_PID" || true
-wait
-exit $EXIT_CODE
diff --git a/test/cpp/naming/resolver_component_tests_runner_invoker.cc b/test/cpp/naming/resolver_component_tests_runner_invoker.cc
index 6d0708e2f2..45c1029caa 100644
--- a/test/cpp/naming/resolver_component_tests_runner_invoker.cc
+++ b/test/cpp/naming/resolver_component_tests_runner_invoker.cc
@@ -184,7 +184,7 @@ int main(int argc, char** argv) {
std::string const bin_dir = my_bin.substr(0, my_bin.rfind('/'));
// Invoke the .sh and .py scripts directly where they are in source code.
grpc::testing::InvokeResolverComponentTestsRunner(
- "test/cpp/naming/resolver_component_tests_runner.sh",
+ "test/cpp/naming/resolver_component_tests_runner.py",
bin_dir + "/" + FLAGS_test_bin_name,
"test/cpp/naming/utils/dns_server.py",
"test/cpp/naming/resolver_test_record_groups.yaml",
diff --git a/test/cpp/naming/utils/dns_resolver.py b/test/cpp/naming/utils/dns_resolver.py
index 6b272444e7..74f4ca2351 100755
--- a/test/cpp/naming/utils/dns_resolver.py
+++ b/test/cpp/naming/utils/dns_resolver.py
@@ -16,9 +16,12 @@
"""Makes DNS queries for A records to specified servers"""
import argparse
-import signal
+import threading
+import time
import twisted.internet.task as task
import twisted.names.client as client
+import twisted.internet.reactor as reactor
+
def main():
argp = argparse.ArgumentParser(description='Make DNS queries for A records')
@@ -31,7 +34,6 @@ def main():
argp.add_argument('-t', '--timeout', default=1, type=int,
help=('Force process exit after this number of seconds.'))
args = argp.parse_args()
- signal.alarm(args.timeout)
def OnResolverResultAvailable(result):
answers, authority, additional = result
for a in answers:
diff --git a/test/cpp/naming/utils/dns_server.py b/test/cpp/naming/utils/dns_server.py
index 9f42f65ee6..1e8e2e3287 100755
--- a/test/cpp/naming/utils/dns_server.py
+++ b/test/cpp/naming/utils/dns_server.py
@@ -20,6 +20,8 @@ import sys
import yaml
import signal
import os
+import threading
+import time
import twisted
import twisted.internet
@@ -33,6 +35,7 @@ import twisted.names.dns
import twisted.names.server
from twisted.names import client, server, common, authority, dns
import argparse
+import platform
_SERVER_HEALTH_CHECK_RECORD_NAME = 'health-check-local-dns-server-is-alive.resolver-tests.grpctestingexp' # missing end '.' for twisted syntax
_SERVER_HEALTH_CHECK_RECORD_DATA = '123.123.123.123'
@@ -115,6 +118,18 @@ def _quit_on_signal(signum, _frame):
sys.stdout.flush()
sys.exit(0)
+def flush_stdout_loop():
+ num_timeouts_so_far = 0
+ sleep_time = 1
+ # Prevent zombies. Tests that use this server are short-lived.
+ max_timeouts = 60 * 2
+ while num_timeouts_so_far < max_timeouts:
+ sys.stdout.flush()
+ time.sleep(sleep_time)
+ num_timeouts_so_far += 1
+ print('Process timeout reached, or cancelled. Exitting 0.')
+ os.kill(os.getpid(), signal.SIGTERM)
+
def main():
argp = argparse.ArgumentParser(description='Local DNS Server for resolver tests')
argp.add_argument('-p', '--port', default=None, type=int,
@@ -123,11 +138,11 @@ def main():
help=('Directory of resolver_test_record_groups.yaml file. '
'Defauls to path needed when the test is invoked as part of run_tests.py.'))
args = argp.parse_args()
- signal.signal(signal.SIGALRM, _quit_on_signal)
signal.signal(signal.SIGTERM, _quit_on_signal)
signal.signal(signal.SIGINT, _quit_on_signal)
- # Prevent zombies. Tests that use this server are short-lived.
- signal.alarm(2 * 60)
+ output_flush_thread = threading.Thread(target=flush_stdout_loop)
+ output_flush_thread.setDaemon(True)
+ output_flush_thread.start()
start_local_dns_server(args)
if __name__ == '__main__':
diff --git a/test/cpp/naming/utils/tcp_connect.py b/test/cpp/naming/utils/tcp_connect.py
index bf7455e3c2..5773c7cae8 100755
--- a/test/cpp/naming/utils/tcp_connect.py
+++ b/test/cpp/naming/utils/tcp_connect.py
@@ -16,8 +16,11 @@
"""Opens a TCP connection to a specified server and then exits."""
import argparse
-import signal
import socket
+import threading
+import time
+import sys
+
def main():
argp = argparse.ArgumentParser(description='Open a TCP handshake to a server')
@@ -28,7 +31,6 @@ def main():
argp.add_argument('-t', '--timeout', default=1, type=int,
help='Force process exit after this number of seconds.')
args = argp.parse_args()
- signal.alarm(args.timeout)
socket.create_connection([args.server_host, args.server_port])
if __name__ == '__main__':
diff --git a/test/cpp/qps/gen_build_yaml.py b/test/cpp/qps/gen_build_yaml.py
index 1ef8f65b0b..776283c25a 100755
--- a/test/cpp/qps/gen_build_yaml.py
+++ b/test/cpp/qps/gen_build_yaml.py
@@ -63,6 +63,11 @@ def guess_cpu(scenario_json, is_tsan):
return (scenario_json['num_clients'] * client +
scenario_json['num_servers'] * server)
+def maybe_exclude_gcov(scenario_json):
+ if scenario_json['client_config']['client_channels'] > 100:
+ return ['gcov']
+ return []
+
print yaml.dump({
'tests': [
{
@@ -76,7 +81,7 @@ print yaml.dump({
'boringssl': True,
'defaults': 'boringssl',
'cpu_cost': guess_cpu(scenario_json, False),
- 'exclude_configs': ['tsan', 'asan'],
+ 'exclude_configs': ['tsan', 'asan'] + maybe_exclude_gcov(scenario_json),
'timeout_seconds': 2*60,
'excluded_poll_engines': scenario_json.get('EXCLUDED_POLL_ENGINES', []),
'auto_timeout_scaling': False
diff --git a/test/cpp/server/BUILD b/test/cpp/server/BUILD
index 7538845803..3f89d6e26e 100644
--- a/test/cpp/server/BUILD
+++ b/test/cpp/server/BUILD
@@ -32,6 +32,19 @@ grpc_cc_test(
)
grpc_cc_test(
+ name = "server_builder_with_socket_mutator_test",
+ srcs = ["server_builder_with_socket_mutator_test.cc"],
+ deps = [
+ "//:grpc++_unsecure",
+ "//src/proto/grpc/testing:echo_proto",
+ "//test/core/util:grpc_test_util_unsecure",
+ ],
+ external_deps = [
+ "gtest",
+ ],
+)
+
+grpc_cc_test(
name = "server_request_call_test",
srcs = ["server_request_call_test.cc"],
deps = [
diff --git a/test/cpp/server/load_reporter/BUILD b/test/cpp/server/load_reporter/BUILD
new file mode 100644
index 0000000000..5cb3a00f82
--- /dev/null
+++ b/test/cpp/server/load_reporter/BUILD
@@ -0,0 +1,31 @@
+# Copyright 2017 gRPC authors.
+#
+# 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.
+
+licenses(["notice"]) # Apache v2
+
+load("//bazel:grpc_build_system.bzl", "grpc_cc_test", "grpc_cc_library", "grpc_cc_binary", "grpc_package")
+
+grpc_package(name = "test/cpp/server/load_reporter")
+
+grpc_cc_test(
+ name = "lb_load_data_store_test",
+ srcs = ["load_data_store_test.cc"],
+ external_deps = [
+ "gtest",
+ ],
+ deps = [
+ "//:lb_load_data_store",
+ "//test/core/util:grpc_test_util",
+ ],
+)
diff --git a/test/cpp/server/load_reporter/load_data_store_test.cc b/test/cpp/server/load_reporter/load_data_store_test.cc
new file mode 100644
index 0000000000..8280dee6a4
--- /dev/null
+++ b/test/cpp/server/load_reporter/load_data_store_test.cc
@@ -0,0 +1,481 @@
+/*
+ *
+ * Copyright 2018 gRPC authors.
+ *
+ * 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 <grpc/impl/codegen/port_platform.h>
+
+#include <set>
+#include <vector>
+
+#include <grpc/grpc.h>
+#include <gtest/gtest.h>
+
+#include "src/cpp/server/load_reporter/load_data_store.h"
+#include "test/core/util/port.h"
+#include "test/core/util/test_config.h"
+
+namespace grpc {
+namespace testing {
+namespace {
+
+using ::grpc::load_reporter::CallMetricValue;
+using ::grpc::load_reporter::LoadDataStore;
+using ::grpc::load_reporter::LoadRecordKey;
+using ::grpc::load_reporter::LoadRecordValue;
+using ::grpc::load_reporter::PerBalancerStore;
+using ::grpc::load_reporter::kInvalidLbId;
+
+class LoadDataStoreTest : public ::testing::Test {
+ public:
+ LoadDataStoreTest()
+ : kKey1(kLbId1, kLbTag1, kUser1, kClientIp1),
+ kKey2(kLbId2, kLbTag2, kUser2, kClientIp2) {}
+
+ // Check whether per_balancer_stores contains a store which was originally
+ // created for <hostname, lb_id, and load_key>.
+ bool PerBalancerStoresContains(
+ const LoadDataStore& load_data_store,
+ const std::set<PerBalancerStore*>* per_balancer_stores,
+ const grpc::string hostname, const grpc::string lb_id,
+ const grpc::string load_key) {
+ auto original_per_balancer_store =
+ load_data_store.FindPerBalancerStore(hostname, lb_id);
+ EXPECT_NE(original_per_balancer_store, nullptr);
+ EXPECT_EQ(original_per_balancer_store->lb_id(), lb_id);
+ EXPECT_EQ(original_per_balancer_store->load_key(), load_key);
+ for (auto per_balancer_store : *per_balancer_stores) {
+ if (per_balancer_store == original_per_balancer_store) {
+ return true;
+ }
+ }
+ return false;
+ }
+
+ grpc::string FormatLbId(size_t index) {
+ return "kLbId" + std::to_string(index);
+ }
+
+ const grpc::string kHostname1 = "kHostname1";
+ const grpc::string kHostname2 = "kHostname2";
+ const grpc::string kLbId1 = "kLbId1";
+ const grpc::string kLbId2 = "kLbId2";
+ const grpc::string kLbId3 = "kLbId3";
+ const grpc::string kLbId4 = "kLbId4";
+ const grpc::string kLoadKey1 = "kLoadKey1";
+ const grpc::string kLoadKey2 = "kLoadKey2";
+ const grpc::string kLbTag1 = "kLbTag1";
+ const grpc::string kLbTag2 = "kLbTag2";
+ const grpc::string kUser1 = "kUser1";
+ const grpc::string kUser2 = "kUser2";
+ const grpc::string kClientIp1 = "00";
+ const grpc::string kClientIp2 = "02";
+ const grpc::string kMetric1 = "kMetric1";
+ const grpc::string kMetric2 = "kMetric2";
+ const LoadRecordKey kKey1;
+ const LoadRecordKey kKey2;
+};
+
+using PerBalancerStoreTest = LoadDataStoreTest;
+
+TEST_F(LoadDataStoreTest, AssignToSelf) {
+ LoadDataStore load_data_store;
+ load_data_store.ReportStreamCreated(kHostname1, kLbId1, kLoadKey1);
+ auto assigned_stores = load_data_store.GetAssignedStores(kHostname1, kLbId1);
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_stores,
+ kHostname1, kLbId1, kLoadKey1));
+}
+
+TEST_F(LoadDataStoreTest, ReassignOrphanStores) {
+ LoadDataStore load_data_store;
+ load_data_store.ReportStreamCreated(kHostname1, kLbId1, kLoadKey1);
+ load_data_store.ReportStreamCreated(kHostname1, kLbId2, kLoadKey1);
+ load_data_store.ReportStreamCreated(kHostname1, kLbId3, kLoadKey2);
+ load_data_store.ReportStreamCreated(kHostname2, kLbId4, kLoadKey1);
+ // 1. Close the second stream.
+ load_data_store.ReportStreamClosed(kHostname1, kLbId2);
+ auto assigned_to_lb_id_1 =
+ load_data_store.GetAssignedStores(kHostname1, kLbId1);
+ // The orphaned store is re-assigned to kLbId1 with the same load key.
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_1,
+ kHostname1, kLbId1, kLoadKey1));
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_1,
+ kHostname1, kLbId2, kLoadKey1));
+ // 2. Close the first stream.
+ load_data_store.ReportStreamClosed(kHostname1, kLbId1);
+ auto assigned_to_lb_id_3 =
+ load_data_store.GetAssignedStores(kHostname1, kLbId3);
+ // The orphaned stores are re-assigned to kLbId3 with the same host,
+ // because there isn't any LB with the same load key.
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_3,
+ kHostname1, kLbId1, kLoadKey1));
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_3,
+ kHostname1, kLbId2, kLoadKey1));
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_3,
+ kHostname1, kLbId3, kLoadKey2));
+ // 3. Close the third stream.
+ load_data_store.ReportStreamClosed(kHostname1, kLbId3);
+ auto assigned_to_lb_id_4 =
+ load_data_store.GetAssignedStores(kHostname2, kLbId4);
+ // There is no active LB for the first host now. kLbId4 is active but
+ // it's for the second host, so it wll NOT adopt the orphaned stores.
+ EXPECT_FALSE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_4,
+ kHostname1, kLbId1, kLoadKey1));
+ EXPECT_FALSE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_4,
+ kHostname1, kLbId2, kLoadKey1));
+ EXPECT_FALSE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_4,
+ kHostname1, kLbId3, kLoadKey2));
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_4,
+ kHostname2, kLbId4, kLoadKey1));
+}
+
+TEST_F(LoadDataStoreTest, OrphanAssignmentIsSticky) {
+ LoadDataStore load_data_store;
+ std::set<grpc::string> active_lb_ids;
+ size_t num_lb_ids = 1000;
+ for (size_t i = 0; i < num_lb_ids; ++i) {
+ load_data_store.ReportStreamCreated(kHostname1, FormatLbId(i), kLoadKey1);
+ active_lb_ids.insert(FormatLbId(i));
+ }
+ grpc::string orphaned_lb_id = FormatLbId(std::rand() % num_lb_ids);
+ load_data_store.ReportStreamClosed(kHostname1, orphaned_lb_id);
+ active_lb_ids.erase(orphaned_lb_id);
+ // Find which LB is assigned the orphaned store.
+ grpc::string assigned_lb_id = "";
+ for (auto lb_id : active_lb_ids) {
+ if (PerBalancerStoresContains(
+ load_data_store,
+ load_data_store.GetAssignedStores(kHostname1, lb_id), kHostname1,
+ orphaned_lb_id, kLoadKey1)) {
+ assigned_lb_id = lb_id;
+ break;
+ }
+ }
+ EXPECT_STRNE(assigned_lb_id.c_str(), "");
+ // Close 10 more stream, skipping the assigned_lb_id. The assignment of
+ // orphaned_lb_id shouldn't change.
+ for (size_t _ = 0; _ < 10; ++_) {
+ grpc::string lb_id_to_close = "";
+ for (auto lb_id : active_lb_ids) {
+ if (lb_id != assigned_lb_id) {
+ lb_id_to_close = lb_id;
+ break;
+ }
+ }
+ EXPECT_STRNE(lb_id_to_close.c_str(), "");
+ load_data_store.ReportStreamClosed(kHostname1, lb_id_to_close);
+ active_lb_ids.erase(lb_id_to_close);
+ EXPECT_TRUE(PerBalancerStoresContains(
+ load_data_store,
+ load_data_store.GetAssignedStores(kHostname1, assigned_lb_id),
+ kHostname1, orphaned_lb_id, kLoadKey1));
+ }
+ // Close the assigned_lb_id, orphaned_lb_id will be re-assigned again.
+ load_data_store.ReportStreamClosed(kHostname1, assigned_lb_id);
+ active_lb_ids.erase(assigned_lb_id);
+ size_t orphaned_lb_id_occurences = 0;
+ for (auto lb_id : active_lb_ids) {
+ if (PerBalancerStoresContains(
+ load_data_store,
+ load_data_store.GetAssignedStores(kHostname1, lb_id), kHostname1,
+ orphaned_lb_id, kLoadKey1)) {
+ orphaned_lb_id_occurences++;
+ }
+ }
+ EXPECT_EQ(orphaned_lb_id_occurences, 1U);
+}
+
+TEST_F(LoadDataStoreTest, HostTemporarilyLoseAllStreams) {
+ LoadDataStore load_data_store;
+ load_data_store.ReportStreamCreated(kHostname1, kLbId1, kLoadKey1);
+ load_data_store.ReportStreamCreated(kHostname2, kLbId2, kLoadKey1);
+ auto store_lb_id_1 = load_data_store.FindPerBalancerStore(kHostname1, kLbId1);
+ auto store_invalid_lb_id_1 =
+ load_data_store.FindPerBalancerStore(kHostname1, kInvalidLbId);
+ EXPECT_FALSE(store_lb_id_1->IsSuspended());
+ EXPECT_FALSE(store_invalid_lb_id_1->IsSuspended());
+ // Disconnect all the streams of the first host.
+ load_data_store.ReportStreamClosed(kHostname1, kLbId1);
+ // All the streams of that host are suspended.
+ EXPECT_TRUE(store_lb_id_1->IsSuspended());
+ EXPECT_TRUE(store_invalid_lb_id_1->IsSuspended());
+ // Detailed load data won't be kept when the PerBalancerStore is suspended.
+ store_lb_id_1->MergeRow(kKey1, LoadRecordValue());
+ store_invalid_lb_id_1->MergeRow(kKey1, LoadRecordValue());
+ EXPECT_EQ(store_lb_id_1->load_record_map().size(), 0U);
+ EXPECT_EQ(store_invalid_lb_id_1->load_record_map().size(), 0U);
+ // The stores for different hosts won't mix, even if the load key is the same.
+ auto assigned_to_lb_id_2 =
+ load_data_store.GetAssignedStores(kHostname2, kLbId2);
+ EXPECT_EQ(assigned_to_lb_id_2->size(), 2U);
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_2,
+ kHostname2, kLbId2, kLoadKey1));
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_2,
+ kHostname2, kInvalidLbId, ""));
+ // A new stream is created for the first host.
+ load_data_store.ReportStreamCreated(kHostname1, kLbId3, kLoadKey2);
+ // The stores for the first host are resumed.
+ EXPECT_FALSE(store_lb_id_1->IsSuspended());
+ EXPECT_FALSE(store_invalid_lb_id_1->IsSuspended());
+ store_lb_id_1->MergeRow(kKey1, LoadRecordValue());
+ store_invalid_lb_id_1->MergeRow(kKey1, LoadRecordValue());
+ EXPECT_EQ(store_lb_id_1->load_record_map().size(), 1U);
+ EXPECT_EQ(store_invalid_lb_id_1->load_record_map().size(), 1U);
+ // The resumed stores are assigned to the new LB.
+ auto assigned_to_lb_id_3 =
+ load_data_store.GetAssignedStores(kHostname1, kLbId3);
+ EXPECT_EQ(assigned_to_lb_id_3->size(), 3U);
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_3,
+ kHostname1, kLbId1, kLoadKey1));
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_3,
+ kHostname1, kInvalidLbId, ""));
+ EXPECT_TRUE(PerBalancerStoresContains(load_data_store, assigned_to_lb_id_3,
+ kHostname1, kLbId3, kLoadKey2));
+}
+
+TEST_F(LoadDataStoreTest, OneStorePerLbId) {
+ LoadDataStore load_data_store;
+ EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname1, kLbId1), nullptr);
+ EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname1, kInvalidLbId),
+ nullptr);
+ EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname2, kLbId2), nullptr);
+ EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname2, kLbId3), nullptr);
+ // Create The first stream.
+ load_data_store.ReportStreamCreated(kHostname1, kLbId1, kLoadKey1);
+ auto store_lb_id_1 = load_data_store.FindPerBalancerStore(kHostname1, kLbId1);
+ auto store_invalid_lb_id_1 =
+ load_data_store.FindPerBalancerStore(kHostname1, kInvalidLbId);
+ // Two stores will be created: one is for the stream; the other one is for
+ // kInvalidLbId.
+ EXPECT_NE(store_lb_id_1, nullptr);
+ EXPECT_NE(store_invalid_lb_id_1, nullptr);
+ EXPECT_NE(store_lb_id_1, store_invalid_lb_id_1);
+ EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname2, kLbId2), nullptr);
+ EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname2, kLbId3), nullptr);
+ // Create the second stream.
+ load_data_store.ReportStreamCreated(kHostname2, kLbId3, kLoadKey1);
+ auto store_lb_id_3 = load_data_store.FindPerBalancerStore(kHostname2, kLbId3);
+ auto store_invalid_lb_id_2 =
+ load_data_store.FindPerBalancerStore(kHostname2, kInvalidLbId);
+ EXPECT_NE(store_lb_id_3, nullptr);
+ EXPECT_NE(store_invalid_lb_id_2, nullptr);
+ EXPECT_NE(store_lb_id_3, store_invalid_lb_id_2);
+ // The PerBalancerStores created for different hosts are independent.
+ EXPECT_NE(store_lb_id_3, store_invalid_lb_id_1);
+ EXPECT_NE(store_invalid_lb_id_2, store_invalid_lb_id_1);
+ EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname2, kLbId2), nullptr);
+}
+
+TEST_F(LoadDataStoreTest, ExactlyOnceAssignment) {
+ LoadDataStore load_data_store;
+ size_t num_create = 100;
+ size_t num_close = 50;
+ for (size_t i = 0; i < num_create; ++i) {
+ load_data_store.ReportStreamCreated(kHostname1, FormatLbId(i), kLoadKey1);
+ }
+ for (size_t i = 0; i < num_close; ++i) {
+ load_data_store.ReportStreamClosed(kHostname1, FormatLbId(i));
+ }
+ std::set<grpc::string> reported_lb_ids;
+ for (size_t i = num_close; i < num_create; ++i) {
+ for (auto assigned_store :
+ *load_data_store.GetAssignedStores(kHostname1, FormatLbId(i))) {
+ EXPECT_TRUE(reported_lb_ids.insert(assigned_store->lb_id()).second);
+ }
+ }
+ // Add one for kInvalidLbId.
+ EXPECT_EQ(reported_lb_ids.size(), (num_create + 1));
+ EXPECT_NE(reported_lb_ids.find(kInvalidLbId), reported_lb_ids.end());
+}
+
+TEST_F(LoadDataStoreTest, UnknownBalancerIdTracking) {
+ LoadDataStore load_data_store;
+ load_data_store.ReportStreamCreated(kHostname1, kLbId1, kLoadKey1);
+ // Merge data for a known LB ID.
+ LoadRecordValue v1(192);
+ load_data_store.MergeRow(kHostname1, kKey1, v1);
+ // Merge data for unknown LB ID.
+ LoadRecordValue v2(23);
+ EXPECT_FALSE(load_data_store.IsTrackedUnknownBalancerId(kLbId2));
+ load_data_store.MergeRow(
+ kHostname1, LoadRecordKey(kLbId2, kLbTag1, kUser1, kClientIp1), v2);
+ EXPECT_TRUE(load_data_store.IsTrackedUnknownBalancerId(kLbId2));
+ LoadRecordValue v3(952);
+ load_data_store.MergeRow(
+ kHostname2, LoadRecordKey(kLbId3, kLbTag1, kUser1, kClientIp1), v3);
+ EXPECT_TRUE(load_data_store.IsTrackedUnknownBalancerId(kLbId3));
+ // The data kept for a known LB ID is correct.
+ auto store_lb_id_1 = load_data_store.FindPerBalancerStore(kHostname1, kLbId1);
+ EXPECT_EQ(store_lb_id_1->load_record_map().size(), 1U);
+ EXPECT_EQ(store_lb_id_1->load_record_map().find(kKey1)->second.start_count(),
+ v1.start_count());
+ EXPECT_EQ(store_lb_id_1->GetNumCallsInProgressForReport(), v1.start_count());
+ // No PerBalancerStore created for Unknown LB ID.
+ EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname1, kLbId2), nullptr);
+ EXPECT_EQ(load_data_store.FindPerBalancerStore(kHostname2, kLbId3), nullptr);
+ // End all the started RPCs for kLbId1.
+ LoadRecordValue v4(0, v1.start_count());
+ load_data_store.MergeRow(kHostname1, kKey1, v4);
+ EXPECT_EQ(store_lb_id_1->load_record_map().size(), 1U);
+ EXPECT_EQ(store_lb_id_1->load_record_map().find(kKey1)->second.start_count(),
+ v1.start_count());
+ EXPECT_EQ(store_lb_id_1->load_record_map().find(kKey1)->second.ok_count(),
+ v4.ok_count());
+ EXPECT_EQ(store_lb_id_1->GetNumCallsInProgressForReport(), 0U);
+ EXPECT_FALSE(load_data_store.IsTrackedUnknownBalancerId(kLbId1));
+ // End all the started RPCs for kLbId2.
+ LoadRecordValue v5(0, v2.start_count());
+ load_data_store.MergeRow(
+ kHostname1, LoadRecordKey(kLbId2, kLbTag1, kUser1, kClientIp1), v5);
+ EXPECT_FALSE(load_data_store.IsTrackedUnknownBalancerId(kLbId2));
+ // End some of the started RPCs for kLbId3.
+ LoadRecordValue v6(0, v3.start_count() / 2);
+ load_data_store.MergeRow(
+ kHostname2, LoadRecordKey(kLbId3, kLbTag1, kUser1, kClientIp1), v6);
+ EXPECT_TRUE(load_data_store.IsTrackedUnknownBalancerId(kLbId3));
+}
+
+TEST_F(PerBalancerStoreTest, Suspend) {
+ PerBalancerStore per_balancer_store(kLbId1, kLoadKey1);
+ EXPECT_FALSE(per_balancer_store.IsSuspended());
+ // Suspend the store.
+ per_balancer_store.Suspend();
+ EXPECT_TRUE(per_balancer_store.IsSuspended());
+ EXPECT_EQ(0U, per_balancer_store.load_record_map().size());
+ // Data merged when the store is suspended won't be kept.
+ LoadRecordValue v1(139, 19);
+ per_balancer_store.MergeRow(kKey1, v1);
+ EXPECT_EQ(0U, per_balancer_store.load_record_map().size());
+ // Resume the store.
+ per_balancer_store.Resume();
+ EXPECT_FALSE(per_balancer_store.IsSuspended());
+ EXPECT_EQ(0U, per_balancer_store.load_record_map().size());
+ // Data merged after the store is resumed will be kept.
+ LoadRecordValue v2(23, 0, 51);
+ per_balancer_store.MergeRow(kKey1, v2);
+ EXPECT_EQ(1U, per_balancer_store.load_record_map().size());
+ // Suspend the store.
+ per_balancer_store.Suspend();
+ EXPECT_TRUE(per_balancer_store.IsSuspended());
+ EXPECT_EQ(0U, per_balancer_store.load_record_map().size());
+ // Data merged when the store is suspended won't be kept.
+ LoadRecordValue v3(62, 11);
+ per_balancer_store.MergeRow(kKey1, v3);
+ EXPECT_EQ(0U, per_balancer_store.load_record_map().size());
+ // Resume the store.
+ per_balancer_store.Resume();
+ EXPECT_FALSE(per_balancer_store.IsSuspended());
+ EXPECT_EQ(0U, per_balancer_store.load_record_map().size());
+ // Data merged after the store is resumed will be kept.
+ LoadRecordValue v4(225, 98);
+ per_balancer_store.MergeRow(kKey1, v4);
+ EXPECT_EQ(1U, per_balancer_store.load_record_map().size());
+ // In-progress count is always kept.
+ EXPECT_EQ(per_balancer_store.GetNumCallsInProgressForReport(),
+ v1.start_count() - v1.ok_count() + v2.start_count() -
+ v2.error_count() + v3.start_count() - v3.ok_count() +
+ v4.start_count() - v4.ok_count());
+}
+
+TEST_F(PerBalancerStoreTest, DataAggregation) {
+ PerBalancerStore per_balancer_store(kLbId1, kLoadKey1);
+ // Construct some Values.
+ LoadRecordValue v1(992, 34, 13, 234.0, 164.0, 173467.38);
+ v1.InsertCallMetric(kMetric1, CallMetricValue(3, 2773.2));
+ LoadRecordValue v2(4842, 213, 9, 393.0, 974.0, 1345.2398);
+ v2.InsertCallMetric(kMetric1, CallMetricValue(7, 25.234));
+ v2.InsertCallMetric(kMetric2, CallMetricValue(2, 387.08));
+ // v3 doesn't change the number of in-progress RPCs.
+ LoadRecordValue v3(293, 55, 293 - 55, 28764, 5284, 5772);
+ v3.InsertCallMetric(kMetric1, CallMetricValue(61, 3465.0));
+ v3.InsertCallMetric(kMetric2, CallMetricValue(13, 672.0));
+ // The initial state of the store.
+ uint64_t num_calls_in_progress = 0;
+ EXPECT_FALSE(per_balancer_store.IsNumCallsInProgressChangedSinceLastReport());
+ EXPECT_EQ(per_balancer_store.GetNumCallsInProgressForReport(),
+ num_calls_in_progress);
+ // Merge v1 and get report of the number of in-progress calls.
+ per_balancer_store.MergeRow(kKey1, v1);
+ EXPECT_TRUE(per_balancer_store.IsNumCallsInProgressChangedSinceLastReport());
+ EXPECT_EQ(per_balancer_store.GetNumCallsInProgressForReport(),
+ num_calls_in_progress +=
+ (v1.start_count() - v1.ok_count() - v1.error_count()));
+ EXPECT_FALSE(per_balancer_store.IsNumCallsInProgressChangedSinceLastReport());
+ // Merge v2 and get report of the number of in-progress calls.
+ per_balancer_store.MergeRow(kKey2, v2);
+ EXPECT_TRUE(per_balancer_store.IsNumCallsInProgressChangedSinceLastReport());
+ EXPECT_EQ(per_balancer_store.GetNumCallsInProgressForReport(),
+ num_calls_in_progress +=
+ (v2.start_count() - v2.ok_count() - v2.error_count()));
+ EXPECT_FALSE(per_balancer_store.IsNumCallsInProgressChangedSinceLastReport());
+ // Merge v3 and get report of the number of in-progress calls.
+ per_balancer_store.MergeRow(kKey1, v3);
+ EXPECT_FALSE(per_balancer_store.IsNumCallsInProgressChangedSinceLastReport());
+ EXPECT_EQ(per_balancer_store.GetNumCallsInProgressForReport(),
+ num_calls_in_progress);
+ // LoadRecordValue for kKey1 is aggregated correctly.
+ LoadRecordValue value_for_key1 =
+ per_balancer_store.load_record_map().find(kKey1)->second;
+ EXPECT_EQ(value_for_key1.start_count(), v1.start_count() + v3.start_count());
+ EXPECT_EQ(value_for_key1.ok_count(), v1.ok_count() + v3.ok_count());
+ EXPECT_EQ(value_for_key1.error_count(), v1.error_count() + v3.error_count());
+ EXPECT_EQ(value_for_key1.bytes_sent(), v1.bytes_sent() + v3.bytes_sent());
+ EXPECT_EQ(value_for_key1.bytes_recv(), v1.bytes_recv() + v3.bytes_recv());
+ EXPECT_EQ(value_for_key1.latency_ms(), v1.latency_ms() + v3.latency_ms());
+ EXPECT_EQ(value_for_key1.call_metrics().size(), 2U);
+ EXPECT_EQ(value_for_key1.call_metrics().find(kMetric1)->second.num_calls(),
+ v1.call_metrics().find(kMetric1)->second.num_calls() +
+ v3.call_metrics().find(kMetric1)->second.num_calls());
+ EXPECT_EQ(
+ value_for_key1.call_metrics().find(kMetric1)->second.total_metric_value(),
+ v1.call_metrics().find(kMetric1)->second.total_metric_value() +
+ v3.call_metrics().find(kMetric1)->second.total_metric_value());
+ EXPECT_EQ(value_for_key1.call_metrics().find(kMetric2)->second.num_calls(),
+ v3.call_metrics().find(kMetric2)->second.num_calls());
+ EXPECT_EQ(
+ value_for_key1.call_metrics().find(kMetric2)->second.total_metric_value(),
+ v3.call_metrics().find(kMetric2)->second.total_metric_value());
+ // LoadRecordValue for kKey2 is aggregated (trivially) correctly.
+ LoadRecordValue value_for_key2 =
+ per_balancer_store.load_record_map().find(kKey2)->second;
+ EXPECT_EQ(value_for_key2.start_count(), v2.start_count());
+ EXPECT_EQ(value_for_key2.ok_count(), v2.ok_count());
+ EXPECT_EQ(value_for_key2.error_count(), v2.error_count());
+ EXPECT_EQ(value_for_key2.bytes_sent(), v2.bytes_sent());
+ EXPECT_EQ(value_for_key2.bytes_recv(), v2.bytes_recv());
+ EXPECT_EQ(value_for_key2.latency_ms(), v2.latency_ms());
+ EXPECT_EQ(value_for_key2.call_metrics().size(), 2U);
+ EXPECT_EQ(value_for_key2.call_metrics().find(kMetric1)->second.num_calls(),
+ v2.call_metrics().find(kMetric1)->second.num_calls());
+ EXPECT_EQ(
+ value_for_key2.call_metrics().find(kMetric1)->second.total_metric_value(),
+ v2.call_metrics().find(kMetric1)->second.total_metric_value());
+ EXPECT_EQ(value_for_key2.call_metrics().find(kMetric2)->second.num_calls(),
+ v2.call_metrics().find(kMetric2)->second.num_calls());
+ EXPECT_EQ(
+ value_for_key2.call_metrics().find(kMetric2)->second.total_metric_value(),
+ v2.call_metrics().find(kMetric2)->second.total_metric_value());
+}
+
+} // namespace
+} // namespace testing
+} // namespace grpc
+
+int main(int argc, char** argv) {
+ grpc_test_init(argc, argv);
+ ::testing::InitGoogleTest(&argc, argv);
+ return RUN_ALL_TESTS();
+}
diff --git a/test/cpp/server/server_builder_with_socket_mutator_test.cc b/test/cpp/server/server_builder_with_socket_mutator_test.cc
new file mode 100644
index 0000000000..5c7dd696c9
--- /dev/null
+++ b/test/cpp/server/server_builder_with_socket_mutator_test.cc
@@ -0,0 +1,116 @@
+/*
+ *
+ * Copyright 2017 gRPC authors.
+ *
+ * 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 <grpcpp/impl/codegen/config.h>
+#include <gtest/gtest.h>
+
+#include <grpcpp/server.h>
+#include <grpcpp/server_builder.h>
+
+#include <grpc/grpc.h>
+#include <memory>
+
+#include "src/core/lib/iomgr/socket_mutator.h"
+#include "src/proto/grpc/testing/echo.grpc.pb.h"
+#include "test/core/util/port.h"
+
+/* This test does a sanity check that grpc_socket_mutator's
+ * are used by servers. It's meant to protect code and end-to-end
+ * tests that rely on this functionality but which live outside
+ * of the grpc github repo. */
+
+namespace grpc {
+namespace {
+
+bool mock_socket_mutator_mutate_fd(int, grpc_socket_mutator*);
+int mock_socket_mutator_compare(grpc_socket_mutator*, grpc_socket_mutator*);
+void mock_socket_mutator_destroy(grpc_socket_mutator*);
+
+const grpc_socket_mutator_vtable mock_socket_mutator_vtable = {
+ mock_socket_mutator_mutate_fd,
+ mock_socket_mutator_compare,
+ mock_socket_mutator_destroy,
+};
+
+class MockSocketMutator : public grpc_socket_mutator {
+ public:
+ MockSocketMutator() : mutate_fd_call_count_(0) {
+ grpc_socket_mutator_init(this, &mock_socket_mutator_vtable);
+ }
+ int mutate_fd_call_count_;
+};
+
+bool mock_socket_mutator_mutate_fd(int fd, grpc_socket_mutator* m) {
+ MockSocketMutator* s = reinterpret_cast<MockSocketMutator*>(m);
+ s->mutate_fd_call_count_++;
+ return true;
+}
+
+int mock_socket_mutator_compare(grpc_socket_mutator* a,
+ grpc_socket_mutator* b) {
+ return (uintptr_t)a - (uintptr_t)b;
+}
+
+void mock_socket_mutator_destroy(grpc_socket_mutator* m) {
+ MockSocketMutator* s = reinterpret_cast<MockSocketMutator*>(m);
+ delete s;
+}
+
+class MockSocketMutatorServerBuilderOption : public grpc::ServerBuilderOption {
+ public:
+ MockSocketMutatorServerBuilderOption(MockSocketMutator* mock_socket_mutator)
+ : mock_socket_mutator_(mock_socket_mutator) {}
+
+ void UpdateArguments(ChannelArguments* args) override {
+ args->SetSocketMutator(mock_socket_mutator_);
+ }
+
+ void UpdatePlugins(
+ std::vector<std::unique_ptr<ServerBuilderPlugin>>*) override{};
+
+ MockSocketMutator* mock_socket_mutator_;
+};
+
+TEST(ServerBuilderWithSocketMutatorTest, CreateServerWithSocketMutator) {
+ auto address = "localhost:" + std::to_string(grpc_pick_unused_port_or_die());
+ auto mock_socket_mutator = new MockSocketMutator();
+ std::unique_ptr<grpc::ServerBuilderOption> mock_socket_mutator_builder_option(
+ new MockSocketMutatorServerBuilderOption(mock_socket_mutator));
+ testing::EchoTestService::Service echo_service;
+ EXPECT_EQ(mock_socket_mutator->mutate_fd_call_count_, 0);
+ ServerBuilder builder;
+ builder.RegisterService(&echo_service);
+ builder.AddListeningPort(address, InsecureServerCredentials());
+ builder.SetOption(std::move(mock_socket_mutator_builder_option));
+ std::unique_ptr<grpc::Server> server(builder.BuildAndStart());
+ EXPECT_NE(server, nullptr);
+ // Only assert that the socket mutator was used.
+ EXPECT_GE(mock_socket_mutator->mutate_fd_call_count_, 1);
+ server->Shutdown();
+}
+
+} // namespace
+} // namespace grpc
+
+int main(int argc, char** argv) {
+ ::testing::InitGoogleTest(&argc, argv);
+ grpc_init();
+ int ret = RUN_ALL_TESTS();
+ grpc_shutdown();
+ return ret;
+}