aboutsummaryrefslogtreecommitdiff
path: root/test/cpp/end2end/client_lb_end2end_test.cc
diff options
context:
space:
mode:
Diffstat (limited to 'test/cpp/end2end/client_lb_end2end_test.cc')
-rw-r--r--test/cpp/end2end/client_lb_end2end_test.cc90
1 files changed, 53 insertions, 37 deletions
diff --git a/test/cpp/end2end/client_lb_end2end_test.cc b/test/cpp/end2end/client_lb_end2end_test.cc
index 33f882bda0..4e0ab6e35f 100644
--- a/test/cpp/end2end/client_lb_end2end_test.cc
+++ b/test/cpp/end2end/client_lb_end2end_test.cc
@@ -26,6 +26,8 @@
#include "absl/memory/memory.h"
#include "absl/strings/str_cat.h"
+#include "absl/strings/str_format.h"
+#include "absl/strings/str_join.h"
#include <grpc/grpc.h>
#include <grpc/support/alloc.h>
@@ -355,32 +357,33 @@ class ClientLbEnd2endTest : public ::testing::Test {
}
struct ServerData {
- int port_;
+ const int port_;
std::unique_ptr<Server> server_;
MyTestServiceImpl service_;
std::unique_ptr<std::thread> thread_;
- bool server_ready_ = false;
- bool started_ = false;
- explicit ServerData(int port = 0) {
- port_ = port > 0 ? port : grpc_pick_unused_port_or_die();
- }
+ grpc::internal::Mutex mu_;
+ grpc::internal::CondVar cond_;
+ bool server_ready_ ABSL_GUARDED_BY(mu_) = false;
+ bool started_ ABSL_GUARDED_BY(mu_) = false;
+
+ explicit ServerData(int port = 0)
+ : port_(port > 0 ? port : grpc_pick_unused_port_or_die()) {}
void Start(const std::string& server_host) {
gpr_log(GPR_INFO, "starting server on port %d", port_);
+ grpc::internal::MutexLock lock(&mu_);
started_ = true;
- grpc::internal::Mutex mu;
- grpc::internal::MutexLock lock(&mu);
- grpc::internal::CondVar cond;
thread_ = absl::make_unique<std::thread>(
- std::bind(&ServerData::Serve, this, server_host, &mu, &cond));
- grpc::internal::WaitUntil(&cond, &mu, [this] { return server_ready_; });
+ std::bind(&ServerData::Serve, this, server_host));
+ while (!server_ready_) {
+ cond_.Wait(&mu_);
+ }
server_ready_ = false;
gpr_log(GPR_INFO, "server startup complete");
}
- void Serve(const std::string& server_host, grpc::internal::Mutex* mu,
- grpc::internal::CondVar* cond) {
+ void Serve(const std::string& server_host) {
std::ostringstream server_address;
server_address << server_host << ":" << port_;
ServerBuilder builder;
@@ -389,12 +392,13 @@ class ClientLbEnd2endTest : public ::testing::Test {
builder.AddListeningPort(server_address.str(), std::move(creds));
builder.RegisterService(&service_);
server_ = builder.BuildAndStart();
- grpc::internal::MutexLock lock(mu);
+ grpc::internal::MutexLock lock(&mu_);
server_ready_ = true;
- cond->Signal();
+ cond_.Signal();
}
void Shutdown() {
+ grpc::internal::MutexLock lock(&mu_);
if (!started_) return;
server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0));
thread_->join();
@@ -1679,11 +1683,26 @@ class ClientLbPickArgsTest : public ClientLbEnd2endTest {
static void TearDownTestCase() { grpc_shutdown(); }
- const std::vector<grpc_core::PickArgsSeen>& args_seen_list() {
+ std::vector<grpc_core::PickArgsSeen> args_seen_list() {
grpc::internal::MutexLock lock(&mu_);
return args_seen_list_;
}
+ static std::string ArgsSeenListString(
+ const std::vector<grpc_core::PickArgsSeen>& args_seen_list) {
+ std::vector<std::string> entries;
+ for (const auto& args_seen : args_seen_list) {
+ std::vector<std::string> metadata;
+ for (const auto& p : args_seen.metadata) {
+ metadata.push_back(absl::StrCat(p.first, "=", p.second));
+ }
+ entries.push_back(absl::StrFormat("{path=\"%s\", metadata=[%s]}",
+ args_seen.path,
+ absl::StrJoin(metadata, ", ")));
+ }
+ return absl::StrCat("[", absl::StrJoin(entries, ", "), "]");
+ }
+
private:
static void SavePickArgs(const grpc_core::PickArgsSeen& args_seen) {
ClientLbPickArgsTest* self = current_test_instance_;
@@ -1705,29 +1724,26 @@ TEST_F(ClientLbPickArgsTest, Basic) {
auto channel = BuildChannel("test_pick_args_lb", response_generator);
auto stub = BuildStub(channel);
response_generator.SetNextResolution(GetServersPorts());
- CheckRpcSendOk(stub, DEBUG_LOCATION, /*wait_for_ready=*/true);
+ // Proactively connect the channel, so that the LB policy will always
+ // be connected before it sees the pick. Otherwise, the test would be
+ // flaky because sometimes the pick would be seen twice (once in
+ // CONNECTING and again in READY) and other times only once (in READY).
+ ASSERT_TRUE(channel->WaitForConnected(gpr_inf_future(GPR_CLOCK_MONOTONIC)));
// Check LB policy name for the channel.
EXPECT_EQ("test_pick_args_lb", channel->GetLoadBalancingPolicyName());
- // There will be two entries, one for the pick tried in state
- // CONNECTING and another for the pick tried in state READY.
- EXPECT_THAT(args_seen_list(),
- ::testing::ElementsAre(
- ::testing::AllOf(
- ::testing::Field(&grpc_core::PickArgsSeen::path,
- "/grpc.testing.EchoTestService/Echo"),
- ::testing::Field(&grpc_core::PickArgsSeen::metadata,
- ::testing::UnorderedElementsAre(
- ::testing::Pair("foo", "1"),
- ::testing::Pair("bar", "2"),
- ::testing::Pair("baz", "3")))),
- ::testing::AllOf(
- ::testing::Field(&grpc_core::PickArgsSeen::path,
- "/grpc.testing.EchoTestService/Echo"),
- ::testing::Field(&grpc_core::PickArgsSeen::metadata,
- ::testing::UnorderedElementsAre(
- ::testing::Pair("foo", "1"),
- ::testing::Pair("bar", "2"),
- ::testing::Pair("baz", "3"))))));
+ // Now send an RPC and check that the picker sees the expected data.
+ CheckRpcSendOk(stub, DEBUG_LOCATION, /*wait_for_ready=*/true);
+ auto pick_args_seen_list = args_seen_list();
+ EXPECT_THAT(pick_args_seen_list,
+ ::testing::ElementsAre(::testing::AllOf(
+ ::testing::Field(&grpc_core::PickArgsSeen::path,
+ "/grpc.testing.EchoTestService/Echo"),
+ ::testing::Field(&grpc_core::PickArgsSeen::metadata,
+ ::testing::UnorderedElementsAre(
+ ::testing::Pair("foo", "1"),
+ ::testing::Pair("bar", "2"),
+ ::testing::Pair("baz", "3"))))))
+ << ArgsSeenListString(pick_args_seen_list);
}
class ClientLbInterceptTrailingMetadataTest : public ClientLbEnd2endTest {