diff options
author | orivej <[email protected]> | 2022-02-10 16:44:49 +0300 |
---|---|---|
committer | Daniil Cherednik <[email protected]> | 2022-02-10 16:44:49 +0300 |
commit | 718c552901d703c502ccbefdfc3c9028d608b947 (patch) | |
tree | 46534a98bbefcd7b1f3faa5b52c138ab27db75b7 /contrib/libs/grpc/test/cpp | |
parent | e9656aae26e0358d5378e5b63dcac5c8dbe0e4d0 (diff) |
Restoring authorship annotation for <[email protected]>. Commit 1 of 2.
Diffstat (limited to 'contrib/libs/grpc/test/cpp')
45 files changed, 8721 insertions, 8721 deletions
diff --git a/contrib/libs/grpc/test/cpp/end2end/cfstream_test.cc b/contrib/libs/grpc/test/cpp/end2end/cfstream_test.cc index e6695982bd7..f814cad5fa5 100644 --- a/contrib/libs/grpc/test/cpp/end2end/cfstream_test.cc +++ b/contrib/libs/grpc/test/cpp/end2end/cfstream_test.cc @@ -1,496 +1,496 @@ -/* - * - * Copyright 2019 The 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 "src/core/lib/iomgr/port.h" - -#include <algorithm> -#include <memory> -#include <mutex> -#include <random> -#include <thread> - -#include <grpc/grpc.h> -#include <grpc/support/alloc.h> -#include <grpc/support/atm.h> -#include <grpc/support/log.h> -#include <grpc/support/string_util.h> -#include <grpc/support/time.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/health_check_service_interface.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <gtest/gtest.h> - -#include "src/core/lib/backoff/backoff.h" -#include "src/core/lib/gpr/env.h" - -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/debugger_macros.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/end2end/test_service_impl.h" -#include "test/cpp/util/test_credentials_provider.h" - -#ifdef GRPC_CFSTREAM -using grpc::ClientAsyncResponseReader; -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; -using grpc::testing::RequestParams; -using std::chrono::system_clock; - -namespace grpc { -namespace testing { -namespace { - -struct TestScenario { +/* + * + * Copyright 2019 The 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 "src/core/lib/iomgr/port.h" + +#include <algorithm> +#include <memory> +#include <mutex> +#include <random> +#include <thread> + +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/atm.h> +#include <grpc/support/log.h> +#include <grpc/support/string_util.h> +#include <grpc/support/time.h> +#include <grpcpp/channel.h> +#include <grpcpp/client_context.h> +#include <grpcpp/create_channel.h> +#include <grpcpp/health_check_service_interface.h> +#include <grpcpp/server.h> +#include <grpcpp/server_builder.h> +#include <gtest/gtest.h> + +#include "src/core/lib/backoff/backoff.h" +#include "src/core/lib/gpr/env.h" + +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/debugger_macros.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/end2end/test_service_impl.h" +#include "test/cpp/util/test_credentials_provider.h" + +#ifdef GRPC_CFSTREAM +using grpc::ClientAsyncResponseReader; +using grpc::testing::EchoRequest; +using grpc::testing::EchoResponse; +using grpc::testing::RequestParams; +using std::chrono::system_clock; + +namespace grpc { +namespace testing { +namespace { + +struct TestScenario { TestScenario(const TString& creds_type, const TString& content) - : credentials_type(creds_type), message_content(content) {} + : credentials_type(creds_type), message_content(content) {} const TString credentials_type; const TString message_content; -}; - -class CFStreamTest : public ::testing::TestWithParam<TestScenario> { - protected: - CFStreamTest() - : server_host_("grpctest"), - interface_("lo0"), - ipv4_address_("10.0.0.1") {} - - void DNSUp() { - std::ostringstream cmd; - // Add DNS entry for server_host_ in /etc/hosts - cmd << "echo '" << ipv4_address_ << " " << server_host_ - << " ' | sudo tee -a /etc/hosts"; - std::system(cmd.str().c_str()); - } - - void DNSDown() { - std::ostringstream cmd; - // Remove DNS entry for server_host_ in /etc/hosts - cmd << "sudo sed -i '.bak' '/" << server_host_ << "/d' /etc/hosts"; - std::system(cmd.str().c_str()); - } - - void InterfaceUp() { - std::ostringstream cmd; - cmd << "sudo /sbin/ifconfig " << interface_ << " alias " << ipv4_address_; - std::system(cmd.str().c_str()); - } - - void InterfaceDown() { - std::ostringstream cmd; - cmd << "sudo /sbin/ifconfig " << interface_ << " -alias " << ipv4_address_; - std::system(cmd.str().c_str()); - } - - void NetworkUp() { - gpr_log(GPR_DEBUG, "Bringing network up"); - InterfaceUp(); - DNSUp(); - } - - void NetworkDown() { - gpr_log(GPR_DEBUG, "Bringing network down"); - InterfaceDown(); - DNSDown(); - } - - void SetUp() override { - NetworkUp(); - grpc_init(); - StartServer(); - } - - void TearDown() override { - NetworkDown(); - StopServer(); - grpc_shutdown(); - } - - void StartServer() { - port_ = grpc_pick_unused_port_or_die(); - server_.reset(new ServerData(port_, GetParam().credentials_type)); - server_->Start(server_host_); - } - void StopServer() { server_->Shutdown(); } - - std::unique_ptr<grpc::testing::EchoTestService::Stub> BuildStub( - const std::shared_ptr<Channel>& channel) { - return grpc::testing::EchoTestService::NewStub(channel); - } - - std::shared_ptr<Channel> BuildChannel() { - std::ostringstream server_address; - server_address << server_host_ << ":" << port_; - ChannelArguments args; - auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( - GetParam().credentials_type, &args); - return CreateCustomChannel(server_address.str(), channel_creds, args); - } - - int GetStreamID(ClientContext& context) { - int stream_id = 0; - grpc_call* call = context.c_call(); - if (call) { - grpc_chttp2_stream* stream = grpc_chttp2_stream_from_call(call); - if (stream) { - stream_id = stream->id; - } - } - return stream_id; - } - - void SendRpc( - const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, - bool expect_success = false) { - auto response = std::unique_ptr<EchoResponse>(new EchoResponse()); - EchoRequest request; - auto& msg = GetParam().message_content; - request.set_message(msg); - ClientContext context; - Status status = stub->Echo(&context, request, response.get()); - int stream_id = GetStreamID(context); - if (status.ok()) { - gpr_log(GPR_DEBUG, "RPC with stream_id %d succeeded", stream_id); - EXPECT_EQ(msg, response->message()); - } else { - gpr_log(GPR_DEBUG, "RPC with stream_id %d failed: %s", stream_id, - status.error_message().c_str()); - } - if (expect_success) { - EXPECT_TRUE(status.ok()); - } - } - void SendAsyncRpc( - const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, - RequestParams param = RequestParams()) { - EchoRequest request; - request.set_message(GetParam().message_content); - *request.mutable_param() = std::move(param); - AsyncClientCall* call = new AsyncClientCall; - - call->response_reader = - stub->PrepareAsyncEcho(&call->context, request, &cq_); - - call->response_reader->StartCall(); - call->response_reader->Finish(&call->reply, &call->status, (void*)call); - } - - void ShutdownCQ() { cq_.Shutdown(); } - - bool CQNext(void** tag, bool* ok) { - auto deadline = std::chrono::system_clock::now() + std::chrono::seconds(10); - auto ret = cq_.AsyncNext(tag, ok, deadline); - if (ret == grpc::CompletionQueue::GOT_EVENT) { - return true; - } else if (ret == grpc::CompletionQueue::SHUTDOWN) { - return false; - } else { - GPR_ASSERT(ret == grpc::CompletionQueue::TIMEOUT); - // This can happen if we hit the Apple CFStream bug which results in the - // read stream hanging. We are ignoring hangs and timeouts, but these - // tests are still useful as they can catch memory memory corruptions, - // crashes and other bugs that don't result in test hang/timeout. - return false; - } - } - - bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { - const gpr_timespec deadline = - grpc_timeout_seconds_to_deadline(timeout_seconds); - grpc_connectivity_state state; - while ((state = channel->GetState(false /* try_to_connect */)) == - GRPC_CHANNEL_READY) { - if (!channel->WaitForStateChange(state, deadline)) return false; - } - return true; - } - - bool WaitForChannelReady(Channel* channel, int timeout_seconds = 10) { - const gpr_timespec deadline = - grpc_timeout_seconds_to_deadline(timeout_seconds); - grpc_connectivity_state state; - while ((state = channel->GetState(true /* try_to_connect */)) != - GRPC_CHANNEL_READY) { - if (!channel->WaitForStateChange(state, deadline)) return false; - } - return true; - } - - struct AsyncClientCall { - EchoResponse reply; - ClientContext context; - Status status; - std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader; - }; - - private: - struct ServerData { - int port_; +}; + +class CFStreamTest : public ::testing::TestWithParam<TestScenario> { + protected: + CFStreamTest() + : server_host_("grpctest"), + interface_("lo0"), + ipv4_address_("10.0.0.1") {} + + void DNSUp() { + std::ostringstream cmd; + // Add DNS entry for server_host_ in /etc/hosts + cmd << "echo '" << ipv4_address_ << " " << server_host_ + << " ' | sudo tee -a /etc/hosts"; + std::system(cmd.str().c_str()); + } + + void DNSDown() { + std::ostringstream cmd; + // Remove DNS entry for server_host_ in /etc/hosts + cmd << "sudo sed -i '.bak' '/" << server_host_ << "/d' /etc/hosts"; + std::system(cmd.str().c_str()); + } + + void InterfaceUp() { + std::ostringstream cmd; + cmd << "sudo /sbin/ifconfig " << interface_ << " alias " << ipv4_address_; + std::system(cmd.str().c_str()); + } + + void InterfaceDown() { + std::ostringstream cmd; + cmd << "sudo /sbin/ifconfig " << interface_ << " -alias " << ipv4_address_; + std::system(cmd.str().c_str()); + } + + void NetworkUp() { + gpr_log(GPR_DEBUG, "Bringing network up"); + InterfaceUp(); + DNSUp(); + } + + void NetworkDown() { + gpr_log(GPR_DEBUG, "Bringing network down"); + InterfaceDown(); + DNSDown(); + } + + void SetUp() override { + NetworkUp(); + grpc_init(); + StartServer(); + } + + void TearDown() override { + NetworkDown(); + StopServer(); + grpc_shutdown(); + } + + void StartServer() { + port_ = grpc_pick_unused_port_or_die(); + server_.reset(new ServerData(port_, GetParam().credentials_type)); + server_->Start(server_host_); + } + void StopServer() { server_->Shutdown(); } + + std::unique_ptr<grpc::testing::EchoTestService::Stub> BuildStub( + const std::shared_ptr<Channel>& channel) { + return grpc::testing::EchoTestService::NewStub(channel); + } + + std::shared_ptr<Channel> BuildChannel() { + std::ostringstream server_address; + server_address << server_host_ << ":" << port_; + ChannelArguments args; + auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( + GetParam().credentials_type, &args); + return CreateCustomChannel(server_address.str(), channel_creds, args); + } + + int GetStreamID(ClientContext& context) { + int stream_id = 0; + grpc_call* call = context.c_call(); + if (call) { + grpc_chttp2_stream* stream = grpc_chttp2_stream_from_call(call); + if (stream) { + stream_id = stream->id; + } + } + return stream_id; + } + + void SendRpc( + const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, + bool expect_success = false) { + auto response = std::unique_ptr<EchoResponse>(new EchoResponse()); + EchoRequest request; + auto& msg = GetParam().message_content; + request.set_message(msg); + ClientContext context; + Status status = stub->Echo(&context, request, response.get()); + int stream_id = GetStreamID(context); + if (status.ok()) { + gpr_log(GPR_DEBUG, "RPC with stream_id %d succeeded", stream_id); + EXPECT_EQ(msg, response->message()); + } else { + gpr_log(GPR_DEBUG, "RPC with stream_id %d failed: %s", stream_id, + status.error_message().c_str()); + } + if (expect_success) { + EXPECT_TRUE(status.ok()); + } + } + void SendAsyncRpc( + const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, + RequestParams param = RequestParams()) { + EchoRequest request; + request.set_message(GetParam().message_content); + *request.mutable_param() = std::move(param); + AsyncClientCall* call = new AsyncClientCall; + + call->response_reader = + stub->PrepareAsyncEcho(&call->context, request, &cq_); + + call->response_reader->StartCall(); + call->response_reader->Finish(&call->reply, &call->status, (void*)call); + } + + void ShutdownCQ() { cq_.Shutdown(); } + + bool CQNext(void** tag, bool* ok) { + auto deadline = std::chrono::system_clock::now() + std::chrono::seconds(10); + auto ret = cq_.AsyncNext(tag, ok, deadline); + if (ret == grpc::CompletionQueue::GOT_EVENT) { + return true; + } else if (ret == grpc::CompletionQueue::SHUTDOWN) { + return false; + } else { + GPR_ASSERT(ret == grpc::CompletionQueue::TIMEOUT); + // This can happen if we hit the Apple CFStream bug which results in the + // read stream hanging. We are ignoring hangs and timeouts, but these + // tests are still useful as they can catch memory memory corruptions, + // crashes and other bugs that don't result in test hang/timeout. + return false; + } + } + + bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(false /* try_to_connect */)) == + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + + bool WaitForChannelReady(Channel* channel, int timeout_seconds = 10) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(true /* try_to_connect */)) != + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + + struct AsyncClientCall { + EchoResponse reply; + ClientContext context; + Status status; + std::unique_ptr<ClientAsyncResponseReader<EchoResponse>> response_reader; + }; + + private: + struct ServerData { + int port_; const TString creds_; - std::unique_ptr<Server> server_; - TestServiceImpl service_; - std::unique_ptr<std::thread> thread_; - bool server_ready_ = false; - + std::unique_ptr<Server> server_; + TestServiceImpl service_; + std::unique_ptr<std::thread> thread_; + bool server_ready_ = false; + ServerData(int port, const TString& creds) - : port_(port), creds_(creds) {} - + : port_(port), creds_(creds) {} + void Start(const TString& server_host) { - gpr_log(GPR_INFO, "starting server on port %d", port_); - std::mutex mu; - std::unique_lock<std::mutex> lock(mu); - std::condition_variable cond; - thread_.reset(new std::thread( - std::bind(&ServerData::Serve, this, server_host, &mu, &cond))); - cond.wait(lock, [this] { return server_ready_; }); - server_ready_ = false; - gpr_log(GPR_INFO, "server startup complete"); - } - + gpr_log(GPR_INFO, "starting server on port %d", port_); + std::mutex mu; + std::unique_lock<std::mutex> lock(mu); + std::condition_variable cond; + thread_.reset(new std::thread( + std::bind(&ServerData::Serve, this, server_host, &mu, &cond))); + cond.wait(lock, [this] { return server_ready_; }); + server_ready_ = false; + gpr_log(GPR_INFO, "server startup complete"); + } + void Serve(const TString& server_host, std::mutex* mu, - std::condition_variable* cond) { - std::ostringstream server_address; - server_address << server_host << ":" << port_; - ServerBuilder builder; - auto server_creds = - GetCredentialsProvider()->GetServerCredentials(creds_); - builder.AddListeningPort(server_address.str(), server_creds); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - std::lock_guard<std::mutex> lock(*mu); - server_ready_ = true; - cond->notify_one(); - } - - void Shutdown(bool join = true) { - server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); - if (join) thread_->join(); - } - }; - - CompletionQueue cq_; + std::condition_variable* cond) { + std::ostringstream server_address; + server_address << server_host << ":" << port_; + ServerBuilder builder; + auto server_creds = + GetCredentialsProvider()->GetServerCredentials(creds_); + builder.AddListeningPort(server_address.str(), server_creds); + builder.RegisterService(&service_); + server_ = builder.BuildAndStart(); + std::lock_guard<std::mutex> lock(*mu); + server_ready_ = true; + cond->notify_one(); + } + + void Shutdown(bool join = true) { + server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); + if (join) thread_->join(); + } + }; + + CompletionQueue cq_; const TString server_host_; const TString interface_; const TString ipv4_address_; - std::unique_ptr<ServerData> server_; - int port_; -}; - -std::vector<TestScenario> CreateTestScenarios() { - std::vector<TestScenario> scenarios; + std::unique_ptr<ServerData> server_; + int port_; +}; + +std::vector<TestScenario> CreateTestScenarios() { + std::vector<TestScenario> scenarios; std::vector<TString> credentials_types; std::vector<TString> messages; - - credentials_types.push_back(kInsecureCredentialsType); - auto sec_list = GetCredentialsProvider()->GetSecureCredentialsTypeList(); - for (auto sec = sec_list.begin(); sec != sec_list.end(); sec++) { - credentials_types.push_back(*sec); - } - - messages.push_back("🖖"); - for (size_t k = 1; k < GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH / 1024; k *= 32) { + + credentials_types.push_back(kInsecureCredentialsType); + auto sec_list = GetCredentialsProvider()->GetSecureCredentialsTypeList(); + for (auto sec = sec_list.begin(); sec != sec_list.end(); sec++) { + credentials_types.push_back(*sec); + } + + messages.push_back("🖖"); + for (size_t k = 1; k < GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH / 1024; k *= 32) { TString big_msg; - for (size_t i = 0; i < k * 1024; ++i) { - char c = 'a' + (i % 26); - big_msg += c; - } - messages.push_back(big_msg); - } - for (auto cred = credentials_types.begin(); cred != credentials_types.end(); - ++cred) { - for (auto msg = messages.begin(); msg != messages.end(); msg++) { - scenarios.emplace_back(*cred, *msg); - } - } - - return scenarios; -} - -INSTANTIATE_TEST_SUITE_P(CFStreamTest, CFStreamTest, - ::testing::ValuesIn(CreateTestScenarios())); - -// gRPC should automatically detech network flaps (without enabling keepalives) -// when CFStream is enabled -TEST_P(CFStreamTest, NetworkTransition) { - auto channel = BuildChannel(); - auto stub = BuildStub(channel); - // Channel should be in READY state after we send an RPC - SendRpc(stub, /*expect_success=*/true); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - - std::atomic_bool shutdown{false}; - std::thread sender = std::thread([this, &stub, &shutdown]() { - while (true) { - if (shutdown.load()) { - return; - } - SendRpc(stub); - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - } - }); - - // bring down network - NetworkDown(); - - // network going down should be detected by cfstream - EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - - // bring network interface back up - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - NetworkUp(); - - // channel should reconnect - EXPECT_TRUE(WaitForChannelReady(channel.get())); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - shutdown.store(true); - sender.join(); -} - -// Network flaps while RPCs are in flight -TEST_P(CFStreamTest, NetworkFlapRpcsInFlight) { - auto channel = BuildChannel(); - auto stub = BuildStub(channel); - std::atomic_int rpcs_sent{0}; - - // Channel should be in READY state after we send some RPCs - for (int i = 0; i < 10; ++i) { - RequestParams param; - param.set_skip_cancelled_check(true); - SendAsyncRpc(stub, param); - ++rpcs_sent; - } - EXPECT_TRUE(WaitForChannelReady(channel.get())); - - // Bring down the network - NetworkDown(); - - std::thread thd = std::thread([this, &rpcs_sent]() { - void* got_tag; - bool ok = false; - bool network_down = true; - int total_completions = 0; - - while (CQNext(&got_tag, &ok)) { - ++total_completions; - GPR_ASSERT(ok); - AsyncClientCall* call = static_cast<AsyncClientCall*>(got_tag); - int stream_id = GetStreamID(call->context); - if (!call->status.ok()) { - gpr_log(GPR_DEBUG, "RPC with stream_id %d failed with error: %s", - stream_id, call->status.error_message().c_str()); - // Bring network up when RPCs start failing - if (network_down) { - NetworkUp(); - network_down = false; - } - } else { - gpr_log(GPR_DEBUG, "RPC with stream_id %d succeeded", stream_id); - } - delete call; - } - // Remove line below and uncomment the following line after Apple CFStream - // bug has been fixed. - (void)rpcs_sent; - // EXPECT_EQ(total_completions, rpcs_sent); - }); - - for (int i = 0; i < 100; ++i) { - RequestParams param; - param.set_skip_cancelled_check(true); - SendAsyncRpc(stub, param); - std::this_thread::sleep_for(std::chrono::milliseconds(10)); - ++rpcs_sent; - } - - ShutdownCQ(); - - thd.join(); -} - -// Send a bunch of RPCs, some of which are expected to fail. -// We should get back a response for all RPCs -TEST_P(CFStreamTest, ConcurrentRpc) { - auto channel = BuildChannel(); - auto stub = BuildStub(channel); - std::atomic_int rpcs_sent{0}; - std::thread thd = std::thread([this, &rpcs_sent]() { - void* got_tag; - bool ok = false; - int total_completions = 0; - - while (CQNext(&got_tag, &ok)) { - ++total_completions; - GPR_ASSERT(ok); - AsyncClientCall* call = static_cast<AsyncClientCall*>(got_tag); - int stream_id = GetStreamID(call->context); - if (!call->status.ok()) { - gpr_log(GPR_DEBUG, "RPC with stream_id %d failed with error: %s", - stream_id, call->status.error_message().c_str()); - // Bring network up when RPCs start failing - } else { - gpr_log(GPR_DEBUG, "RPC with stream_id %d succeeded", stream_id); - } - delete call; - } - // Remove line below and uncomment the following line after Apple CFStream - // bug has been fixed. - (void)rpcs_sent; - // EXPECT_EQ(total_completions, rpcs_sent); - }); - - for (int i = 0; i < 10; ++i) { - if (i % 3 == 0) { - RequestParams param; - ErrorStatus* error = param.mutable_expected_error(); - error->set_code(StatusCode::INTERNAL); - error->set_error_message("internal error"); - SendAsyncRpc(stub, param); - } else if (i % 5 == 0) { - RequestParams param; - param.set_echo_metadata(true); - DebugInfo* info = param.mutable_debug_info(); - info->add_stack_entries("stack_entry1"); - info->add_stack_entries("stack_entry2"); - info->set_detail("detailed debug info"); - SendAsyncRpc(stub, param); - } else { - SendAsyncRpc(stub); - } - ++rpcs_sent; - } - - ShutdownCQ(); - - thd.join(); -} - -} // namespace -} // namespace testing -} // namespace grpc -#endif // GRPC_CFSTREAM - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); + for (size_t i = 0; i < k * 1024; ++i) { + char c = 'a' + (i % 26); + big_msg += c; + } + messages.push_back(big_msg); + } + for (auto cred = credentials_types.begin(); cred != credentials_types.end(); + ++cred) { + for (auto msg = messages.begin(); msg != messages.end(); msg++) { + scenarios.emplace_back(*cred, *msg); + } + } + + return scenarios; +} + +INSTANTIATE_TEST_SUITE_P(CFStreamTest, CFStreamTest, + ::testing::ValuesIn(CreateTestScenarios())); + +// gRPC should automatically detech network flaps (without enabling keepalives) +// when CFStream is enabled +TEST_P(CFStreamTest, NetworkTransition) { + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + SendRpc(stub, /*expect_success=*/true); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + std::atomic_bool shutdown{false}; + std::thread sender = std::thread([this, &stub, &shutdown]() { + while (true) { + if (shutdown.load()) { + return; + } + SendRpc(stub); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + } + }); + + // bring down network + NetworkDown(); + + // network going down should be detected by cfstream + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + + // bring network interface back up + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + NetworkUp(); + + // channel should reconnect + EXPECT_TRUE(WaitForChannelReady(channel.get())); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + shutdown.store(true); + sender.join(); +} + +// Network flaps while RPCs are in flight +TEST_P(CFStreamTest, NetworkFlapRpcsInFlight) { + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + std::atomic_int rpcs_sent{0}; + + // Channel should be in READY state after we send some RPCs + for (int i = 0; i < 10; ++i) { + RequestParams param; + param.set_skip_cancelled_check(true); + SendAsyncRpc(stub, param); + ++rpcs_sent; + } + EXPECT_TRUE(WaitForChannelReady(channel.get())); + + // Bring down the network + NetworkDown(); + + std::thread thd = std::thread([this, &rpcs_sent]() { + void* got_tag; + bool ok = false; + bool network_down = true; + int total_completions = 0; + + while (CQNext(&got_tag, &ok)) { + ++total_completions; + GPR_ASSERT(ok); + AsyncClientCall* call = static_cast<AsyncClientCall*>(got_tag); + int stream_id = GetStreamID(call->context); + if (!call->status.ok()) { + gpr_log(GPR_DEBUG, "RPC with stream_id %d failed with error: %s", + stream_id, call->status.error_message().c_str()); + // Bring network up when RPCs start failing + if (network_down) { + NetworkUp(); + network_down = false; + } + } else { + gpr_log(GPR_DEBUG, "RPC with stream_id %d succeeded", stream_id); + } + delete call; + } + // Remove line below and uncomment the following line after Apple CFStream + // bug has been fixed. + (void)rpcs_sent; + // EXPECT_EQ(total_completions, rpcs_sent); + }); + + for (int i = 0; i < 100; ++i) { + RequestParams param; + param.set_skip_cancelled_check(true); + SendAsyncRpc(stub, param); + std::this_thread::sleep_for(std::chrono::milliseconds(10)); + ++rpcs_sent; + } + + ShutdownCQ(); + + thd.join(); +} + +// Send a bunch of RPCs, some of which are expected to fail. +// We should get back a response for all RPCs +TEST_P(CFStreamTest, ConcurrentRpc) { + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + std::atomic_int rpcs_sent{0}; + std::thread thd = std::thread([this, &rpcs_sent]() { + void* got_tag; + bool ok = false; + int total_completions = 0; + + while (CQNext(&got_tag, &ok)) { + ++total_completions; + GPR_ASSERT(ok); + AsyncClientCall* call = static_cast<AsyncClientCall*>(got_tag); + int stream_id = GetStreamID(call->context); + if (!call->status.ok()) { + gpr_log(GPR_DEBUG, "RPC with stream_id %d failed with error: %s", + stream_id, call->status.error_message().c_str()); + // Bring network up when RPCs start failing + } else { + gpr_log(GPR_DEBUG, "RPC with stream_id %d succeeded", stream_id); + } + delete call; + } + // Remove line below and uncomment the following line after Apple CFStream + // bug has been fixed. + (void)rpcs_sent; + // EXPECT_EQ(total_completions, rpcs_sent); + }); + + for (int i = 0; i < 10; ++i) { + if (i % 3 == 0) { + RequestParams param; + ErrorStatus* error = param.mutable_expected_error(); + error->set_code(StatusCode::INTERNAL); + error->set_error_message("internal error"); + SendAsyncRpc(stub, param); + } else if (i % 5 == 0) { + RequestParams param; + param.set_echo_metadata(true); + DebugInfo* info = param.mutable_debug_info(); + info->add_stack_entries("stack_entry1"); + info->add_stack_entries("stack_entry2"); + info->set_detail("detailed debug info"); + SendAsyncRpc(stub, param); + } else { + SendAsyncRpc(stub); + } + ++rpcs_sent; + } + + ShutdownCQ(); + + thd.join(); +} + +} // namespace +} // namespace testing +} // namespace grpc +#endif // GRPC_CFSTREAM + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); grpc::testing::TestEnvironment env(argc, argv); - gpr_setenv("grpc_cfstream", "1"); - const auto result = RUN_ALL_TESTS(); - return result; -} + gpr_setenv("grpc_cfstream", "1"); + const auto result = RUN_ALL_TESTS(); + return result; +} diff --git a/contrib/libs/grpc/test/cpp/end2end/delegating_channel_test.cc b/contrib/libs/grpc/test/cpp/end2end/delegating_channel_test.cc index 5d025ecb943..6fd6652a2bb 100644 --- a/contrib/libs/grpc/test/cpp/end2end/delegating_channel_test.cc +++ b/contrib/libs/grpc/test/cpp/end2end/delegating_channel_test.cc @@ -1,100 +1,100 @@ -/* - * - * 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 <memory> -#include <vector> - -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/generic/generic_stub.h> -#include <grpcpp/impl/codegen/delegating_channel.h> -#include <grpcpp/impl/codegen/proto_utils.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> -#include <grpcpp/support/client_interceptor.h> - -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/end2end/test_service_impl.h" -#include "test/cpp/util/byte_buffer_proto_helper.h" -#include "test/cpp/util/string_ref_helper.h" - -#include <gtest/gtest.h> - -namespace grpc { -namespace testing { -namespace { - -class TestChannel : public experimental::DelegatingChannel { - public: - TestChannel(const std::shared_ptr<ChannelInterface>& delegate_channel) - : experimental::DelegatingChannel(delegate_channel) {} - // Always returns GRPC_CHANNEL_READY - grpc_connectivity_state GetState(bool /*try_to_connect*/) override { - return GRPC_CHANNEL_READY; - } -}; - -class DelegatingChannelTest : public ::testing::Test { - protected: - DelegatingChannelTest() { - int port = grpc_pick_unused_port_or_die(); - ServerBuilder builder; +/* + * + * 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 <memory> +#include <vector> + +#include <grpcpp/channel.h> +#include <grpcpp/client_context.h> +#include <grpcpp/create_channel.h> +#include <grpcpp/generic/generic_stub.h> +#include <grpcpp/impl/codegen/delegating_channel.h> +#include <grpcpp/impl/codegen/proto_utils.h> +#include <grpcpp/server.h> +#include <grpcpp/server_builder.h> +#include <grpcpp/server_context.h> +#include <grpcpp/support/client_interceptor.h> + +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/end2end/test_service_impl.h" +#include "test/cpp/util/byte_buffer_proto_helper.h" +#include "test/cpp/util/string_ref_helper.h" + +#include <gtest/gtest.h> + +namespace grpc { +namespace testing { +namespace { + +class TestChannel : public experimental::DelegatingChannel { + public: + TestChannel(const std::shared_ptr<ChannelInterface>& delegate_channel) + : experimental::DelegatingChannel(delegate_channel) {} + // Always returns GRPC_CHANNEL_READY + grpc_connectivity_state GetState(bool /*try_to_connect*/) override { + return GRPC_CHANNEL_READY; + } +}; + +class DelegatingChannelTest : public ::testing::Test { + protected: + DelegatingChannelTest() { + int port = grpc_pick_unused_port_or_die(); + ServerBuilder builder; server_address_ = "localhost:" + ToString(port); - builder.AddListeningPort(server_address_, InsecureServerCredentials()); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - } - - ~DelegatingChannelTest() { server_->Shutdown(); } - + builder.AddListeningPort(server_address_, InsecureServerCredentials()); + builder.RegisterService(&service_); + server_ = builder.BuildAndStart(); + } + + ~DelegatingChannelTest() { server_->Shutdown(); } + TString server_address_; - TestServiceImpl service_; - std::unique_ptr<Server> server_; -}; - -TEST_F(DelegatingChannelTest, SimpleTest) { - auto channel = CreateChannel(server_address_, InsecureChannelCredentials()); - std::shared_ptr<TestChannel> test_channel = - std::make_shared<TestChannel>(channel); - // gRPC channel should be in idle state at this point but our test channel - // will return ready. - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_IDLE); - EXPECT_EQ(test_channel->GetState(false), GRPC_CHANNEL_READY); - auto stub = grpc::testing::EchoTestService::NewStub(test_channel); - ClientContext ctx; - EchoRequest req; - req.set_message("Hello"); - EchoResponse resp; - Status s = stub->Echo(&ctx, req, &resp); - EXPECT_EQ(s.ok(), true); - EXPECT_EQ(resp.message(), "Hello"); -} - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} + TestServiceImpl service_; + std::unique_ptr<Server> server_; +}; + +TEST_F(DelegatingChannelTest, SimpleTest) { + auto channel = CreateChannel(server_address_, InsecureChannelCredentials()); + std::shared_ptr<TestChannel> test_channel = + std::make_shared<TestChannel>(channel); + // gRPC channel should be in idle state at this point but our test channel + // will return ready. + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_IDLE); + EXPECT_EQ(test_channel->GetState(false), GRPC_CHANNEL_READY); + auto stub = grpc::testing::EchoTestService::NewStub(test_channel); + ClientContext ctx; + EchoRequest req; + req.set_message("Hello"); + EchoResponse resp; + Status s = stub->Echo(&ctx, req, &resp); + EXPECT_EQ(s.ok(), true); + EXPECT_EQ(resp.message(), "Hello"); +} + +} // namespace +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + grpc::testing::TestEnvironment env(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/contrib/libs/grpc/test/cpp/end2end/flaky_network_test.cc b/contrib/libs/grpc/test/cpp/end2end/flaky_network_test.cc index 3ee75952c03..3e7f9ed7936 100644 --- a/contrib/libs/grpc/test/cpp/end2end/flaky_network_test.cc +++ b/contrib/libs/grpc/test/cpp/end2end/flaky_network_test.cc @@ -1,558 +1,558 @@ -/* - * - * Copyright 2019 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/grpc.h> -#include <grpc/support/alloc.h> -#include <grpc/support/atm.h> -#include <grpc/support/log.h> -#include <grpc/support/port_platform.h> -#include <grpc/support/string_util.h> -#include <grpc/support/time.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/health_check_service_interface.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <gtest/gtest.h> - -#include <algorithm> -#include <condition_variable> -#include <memory> -#include <mutex> -#include <random> -#include <thread> - -#include "src/core/lib/backoff/backoff.h" -#include "src/core/lib/gpr/env.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/debugger_macros.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/end2end/test_service_impl.h" -#include "test/cpp/util/test_credentials_provider.h" - -#ifdef GPR_LINUX -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; - -namespace grpc { -namespace testing { -namespace { - -struct TestScenario { +/* + * + * Copyright 2019 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/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/atm.h> +#include <grpc/support/log.h> +#include <grpc/support/port_platform.h> +#include <grpc/support/string_util.h> +#include <grpc/support/time.h> +#include <grpcpp/channel.h> +#include <grpcpp/client_context.h> +#include <grpcpp/create_channel.h> +#include <grpcpp/health_check_service_interface.h> +#include <grpcpp/server.h> +#include <grpcpp/server_builder.h> +#include <gtest/gtest.h> + +#include <algorithm> +#include <condition_variable> +#include <memory> +#include <mutex> +#include <random> +#include <thread> + +#include "src/core/lib/backoff/backoff.h" +#include "src/core/lib/gpr/env.h" +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/debugger_macros.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/end2end/test_service_impl.h" +#include "test/cpp/util/test_credentials_provider.h" + +#ifdef GPR_LINUX +using grpc::testing::EchoRequest; +using grpc::testing::EchoResponse; + +namespace grpc { +namespace testing { +namespace { + +struct TestScenario { TestScenario(const TString& creds_type, const TString& content) - : credentials_type(creds_type), message_content(content) {} + : credentials_type(creds_type), message_content(content) {} const TString credentials_type; const TString message_content; -}; - -class FlakyNetworkTest : public ::testing::TestWithParam<TestScenario> { - protected: - FlakyNetworkTest() - : server_host_("grpctest"), - interface_("lo:1"), - ipv4_address_("10.0.0.1"), - netmask_("/32") {} - - void InterfaceUp() { - std::ostringstream cmd; - // create interface_ with address ipv4_address_ - cmd << "ip addr add " << ipv4_address_ << netmask_ << " dev " << interface_; - std::system(cmd.str().c_str()); - } - - void InterfaceDown() { - std::ostringstream cmd; - // remove interface_ - cmd << "ip addr del " << ipv4_address_ << netmask_ << " dev " << interface_; - std::system(cmd.str().c_str()); - } - - void DNSUp() { - std::ostringstream cmd; - // Add DNS entry for server_host_ in /etc/hosts - cmd << "echo '" << ipv4_address_ << " " << server_host_ - << "' >> /etc/hosts"; - std::system(cmd.str().c_str()); - } - - void DNSDown() { - std::ostringstream cmd; - // Remove DNS entry for server_host_ from /etc/hosts - // NOTE: we can't do this in one step with sed -i because when we are - // running under docker, the file is mounted by docker so we can't change - // its inode from within the container (sed -i creates a new file and - // replaces the old file, which changes the inode) - cmd << "sed '/" << server_host_ << "/d' /etc/hosts > /etc/hosts.orig"; - std::system(cmd.str().c_str()); - - // clear the stream - cmd.str(""); - - cmd << "cat /etc/hosts.orig > /etc/hosts"; - std::system(cmd.str().c_str()); - } - - void DropPackets() { - std::ostringstream cmd; - // drop packets with src IP = ipv4_address_ - cmd << "iptables -A INPUT -s " << ipv4_address_ << " -j DROP"; - - std::system(cmd.str().c_str()); - // clear the stream - cmd.str(""); - - // drop packets with dst IP = ipv4_address_ - cmd << "iptables -A INPUT -d " << ipv4_address_ << " -j DROP"; - } - - void RestoreNetwork() { - std::ostringstream cmd; - // remove iptables rule to drop packets with src IP = ipv4_address_ - cmd << "iptables -D INPUT -s " << ipv4_address_ << " -j DROP"; - std::system(cmd.str().c_str()); - // clear the stream - cmd.str(""); - // remove iptables rule to drop packets with dest IP = ipv4_address_ - cmd << "iptables -D INPUT -d " << ipv4_address_ << " -j DROP"; - } - - void FlakeNetwork() { - std::ostringstream cmd; - // Emulate a flaky network connection over interface_. Add a delay of 100ms - // +/- 20ms, 0.1% packet loss, 1% duplicates and 0.01% corrupt packets. - cmd << "tc qdisc replace dev " << interface_ - << " root netem delay 100ms 20ms distribution normal loss 0.1% " - "duplicate " - "0.1% corrupt 0.01% "; - std::system(cmd.str().c_str()); - } - - void UnflakeNetwork() { - // Remove simulated network flake on interface_ - std::ostringstream cmd; - cmd << "tc qdisc del dev " << interface_ << " root netem"; - std::system(cmd.str().c_str()); - } - - void NetworkUp() { - InterfaceUp(); - DNSUp(); - } - - void NetworkDown() { - InterfaceDown(); - DNSDown(); - } - - void SetUp() override { - NetworkUp(); - grpc_init(); - StartServer(); - } - - void TearDown() override { - NetworkDown(); - StopServer(); - grpc_shutdown(); - } - - void StartServer() { - // TODO (pjaikumar): Ideally, we should allocate the port dynamically using - // grpc_pick_unused_port_or_die(). That doesn't work inside some docker - // containers because port_server listens on localhost which maps to - // ip6-looopback, but ipv6 support is not enabled by default in docker. - port_ = SERVER_PORT; - - server_.reset(new ServerData(port_, GetParam().credentials_type)); - server_->Start(server_host_); - } - void StopServer() { server_->Shutdown(); } - - std::unique_ptr<grpc::testing::EchoTestService::Stub> BuildStub( - const std::shared_ptr<Channel>& channel) { - return grpc::testing::EchoTestService::NewStub(channel); - } - - std::shared_ptr<Channel> BuildChannel( +}; + +class FlakyNetworkTest : public ::testing::TestWithParam<TestScenario> { + protected: + FlakyNetworkTest() + : server_host_("grpctest"), + interface_("lo:1"), + ipv4_address_("10.0.0.1"), + netmask_("/32") {} + + void InterfaceUp() { + std::ostringstream cmd; + // create interface_ with address ipv4_address_ + cmd << "ip addr add " << ipv4_address_ << netmask_ << " dev " << interface_; + std::system(cmd.str().c_str()); + } + + void InterfaceDown() { + std::ostringstream cmd; + // remove interface_ + cmd << "ip addr del " << ipv4_address_ << netmask_ << " dev " << interface_; + std::system(cmd.str().c_str()); + } + + void DNSUp() { + std::ostringstream cmd; + // Add DNS entry for server_host_ in /etc/hosts + cmd << "echo '" << ipv4_address_ << " " << server_host_ + << "' >> /etc/hosts"; + std::system(cmd.str().c_str()); + } + + void DNSDown() { + std::ostringstream cmd; + // Remove DNS entry for server_host_ from /etc/hosts + // NOTE: we can't do this in one step with sed -i because when we are + // running under docker, the file is mounted by docker so we can't change + // its inode from within the container (sed -i creates a new file and + // replaces the old file, which changes the inode) + cmd << "sed '/" << server_host_ << "/d' /etc/hosts > /etc/hosts.orig"; + std::system(cmd.str().c_str()); + + // clear the stream + cmd.str(""); + + cmd << "cat /etc/hosts.orig > /etc/hosts"; + std::system(cmd.str().c_str()); + } + + void DropPackets() { + std::ostringstream cmd; + // drop packets with src IP = ipv4_address_ + cmd << "iptables -A INPUT -s " << ipv4_address_ << " -j DROP"; + + std::system(cmd.str().c_str()); + // clear the stream + cmd.str(""); + + // drop packets with dst IP = ipv4_address_ + cmd << "iptables -A INPUT -d " << ipv4_address_ << " -j DROP"; + } + + void RestoreNetwork() { + std::ostringstream cmd; + // remove iptables rule to drop packets with src IP = ipv4_address_ + cmd << "iptables -D INPUT -s " << ipv4_address_ << " -j DROP"; + std::system(cmd.str().c_str()); + // clear the stream + cmd.str(""); + // remove iptables rule to drop packets with dest IP = ipv4_address_ + cmd << "iptables -D INPUT -d " << ipv4_address_ << " -j DROP"; + } + + void FlakeNetwork() { + std::ostringstream cmd; + // Emulate a flaky network connection over interface_. Add a delay of 100ms + // +/- 20ms, 0.1% packet loss, 1% duplicates and 0.01% corrupt packets. + cmd << "tc qdisc replace dev " << interface_ + << " root netem delay 100ms 20ms distribution normal loss 0.1% " + "duplicate " + "0.1% corrupt 0.01% "; + std::system(cmd.str().c_str()); + } + + void UnflakeNetwork() { + // Remove simulated network flake on interface_ + std::ostringstream cmd; + cmd << "tc qdisc del dev " << interface_ << " root netem"; + std::system(cmd.str().c_str()); + } + + void NetworkUp() { + InterfaceUp(); + DNSUp(); + } + + void NetworkDown() { + InterfaceDown(); + DNSDown(); + } + + void SetUp() override { + NetworkUp(); + grpc_init(); + StartServer(); + } + + void TearDown() override { + NetworkDown(); + StopServer(); + grpc_shutdown(); + } + + void StartServer() { + // TODO (pjaikumar): Ideally, we should allocate the port dynamically using + // grpc_pick_unused_port_or_die(). That doesn't work inside some docker + // containers because port_server listens on localhost which maps to + // ip6-looopback, but ipv6 support is not enabled by default in docker. + port_ = SERVER_PORT; + + server_.reset(new ServerData(port_, GetParam().credentials_type)); + server_->Start(server_host_); + } + void StopServer() { server_->Shutdown(); } + + std::unique_ptr<grpc::testing::EchoTestService::Stub> BuildStub( + const std::shared_ptr<Channel>& channel) { + return grpc::testing::EchoTestService::NewStub(channel); + } + + std::shared_ptr<Channel> BuildChannel( const TString& lb_policy_name, - ChannelArguments args = ChannelArguments()) { - if (lb_policy_name.size() > 0) { - args.SetLoadBalancingPolicyName(lb_policy_name); - } // else, default to pick first - auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( - GetParam().credentials_type, &args); - std::ostringstream server_address; - server_address << server_host_ << ":" << port_; - return CreateCustomChannel(server_address.str(), channel_creds, args); - } - - bool SendRpc( - const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, - int timeout_ms = 0, bool wait_for_ready = false) { - auto response = std::unique_ptr<EchoResponse>(new EchoResponse()); - EchoRequest request; - auto& msg = GetParam().message_content; - request.set_message(msg); - ClientContext context; - if (timeout_ms > 0) { - context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms)); + ChannelArguments args = ChannelArguments()) { + if (lb_policy_name.size() > 0) { + args.SetLoadBalancingPolicyName(lb_policy_name); + } // else, default to pick first + auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( + GetParam().credentials_type, &args); + std::ostringstream server_address; + server_address << server_host_ << ":" << port_; + return CreateCustomChannel(server_address.str(), channel_creds, args); + } + + bool SendRpc( + const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, + int timeout_ms = 0, bool wait_for_ready = false) { + auto response = std::unique_ptr<EchoResponse>(new EchoResponse()); + EchoRequest request; + auto& msg = GetParam().message_content; + request.set_message(msg); + ClientContext context; + if (timeout_ms > 0) { + context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms)); // Allow an RPC to be canceled (for deadline exceeded) after it has // reached the server. request.mutable_param()->set_skip_cancelled_check(true); - } - // See https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md for - // details of wait-for-ready semantics - if (wait_for_ready) { - context.set_wait_for_ready(true); - } - Status status = stub->Echo(&context, request, response.get()); - auto ok = status.ok(); - int stream_id = 0; - grpc_call* call = context.c_call(); - if (call) { - grpc_chttp2_stream* stream = grpc_chttp2_stream_from_call(call); - if (stream) { - stream_id = stream->id; - } - } - if (ok) { - gpr_log(GPR_DEBUG, "RPC with stream_id %d succeeded", stream_id); - } else { - gpr_log(GPR_DEBUG, "RPC with stream_id %d failed: %s", stream_id, - status.error_message().c_str()); - } - return ok; - } - - struct ServerData { - int port_; + } + // See https://github.com/grpc/grpc/blob/master/doc/wait-for-ready.md for + // details of wait-for-ready semantics + if (wait_for_ready) { + context.set_wait_for_ready(true); + } + Status status = stub->Echo(&context, request, response.get()); + auto ok = status.ok(); + int stream_id = 0; + grpc_call* call = context.c_call(); + if (call) { + grpc_chttp2_stream* stream = grpc_chttp2_stream_from_call(call); + if (stream) { + stream_id = stream->id; + } + } + if (ok) { + gpr_log(GPR_DEBUG, "RPC with stream_id %d succeeded", stream_id); + } else { + gpr_log(GPR_DEBUG, "RPC with stream_id %d failed: %s", stream_id, + status.error_message().c_str()); + } + return ok; + } + + struct ServerData { + int port_; const TString creds_; - std::unique_ptr<Server> server_; - TestServiceImpl service_; - std::unique_ptr<std::thread> thread_; - bool server_ready_ = false; - + std::unique_ptr<Server> server_; + TestServiceImpl service_; + std::unique_ptr<std::thread> thread_; + bool server_ready_ = false; + ServerData(int port, const TString& creds) - : port_(port), creds_(creds) {} - + : port_(port), creds_(creds) {} + void Start(const TString& server_host) { - gpr_log(GPR_INFO, "starting server on port %d", port_); - std::mutex mu; - std::unique_lock<std::mutex> lock(mu); - std::condition_variable cond; - thread_.reset(new std::thread( - std::bind(&ServerData::Serve, this, server_host, &mu, &cond))); - cond.wait(lock, [this] { return server_ready_; }); - server_ready_ = false; - gpr_log(GPR_INFO, "server startup complete"); - } - + gpr_log(GPR_INFO, "starting server on port %d", port_); + std::mutex mu; + std::unique_lock<std::mutex> lock(mu); + std::condition_variable cond; + thread_.reset(new std::thread( + std::bind(&ServerData::Serve, this, server_host, &mu, &cond))); + cond.wait(lock, [this] { return server_ready_; }); + server_ready_ = false; + gpr_log(GPR_INFO, "server startup complete"); + } + void Serve(const TString& server_host, std::mutex* mu, - std::condition_variable* cond) { - std::ostringstream server_address; - server_address << server_host << ":" << port_; - ServerBuilder builder; - auto server_creds = - GetCredentialsProvider()->GetServerCredentials(creds_); - builder.AddListeningPort(server_address.str(), server_creds); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - std::lock_guard<std::mutex> lock(*mu); - server_ready_ = true; - cond->notify_one(); - } - - void Shutdown() { - server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); - thread_->join(); - } - }; - - bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { - const gpr_timespec deadline = - grpc_timeout_seconds_to_deadline(timeout_seconds); - grpc_connectivity_state state; - while ((state = channel->GetState(false /* try_to_connect */)) == - GRPC_CHANNEL_READY) { - if (!channel->WaitForStateChange(state, deadline)) return false; - } - return true; - } - - bool WaitForChannelReady(Channel* channel, int timeout_seconds = 5) { - const gpr_timespec deadline = - grpc_timeout_seconds_to_deadline(timeout_seconds); - grpc_connectivity_state state; - while ((state = channel->GetState(true /* try_to_connect */)) != - GRPC_CHANNEL_READY) { - if (!channel->WaitForStateChange(state, deadline)) return false; - } - return true; - } - - private: + std::condition_variable* cond) { + std::ostringstream server_address; + server_address << server_host << ":" << port_; + ServerBuilder builder; + auto server_creds = + GetCredentialsProvider()->GetServerCredentials(creds_); + builder.AddListeningPort(server_address.str(), server_creds); + builder.RegisterService(&service_); + server_ = builder.BuildAndStart(); + std::lock_guard<std::mutex> lock(*mu); + server_ready_ = true; + cond->notify_one(); + } + + void Shutdown() { + server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); + thread_->join(); + } + }; + + bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(false /* try_to_connect */)) == + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + + bool WaitForChannelReady(Channel* channel, int timeout_seconds = 5) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(true /* try_to_connect */)) != + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + + private: const TString server_host_; const TString interface_; const TString ipv4_address_; const TString netmask_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::unique_ptr<ServerData> server_; - const int SERVER_PORT = 32750; - int port_; -}; - -std::vector<TestScenario> CreateTestScenarios() { - std::vector<TestScenario> scenarios; + std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; + std::unique_ptr<ServerData> server_; + const int SERVER_PORT = 32750; + int port_; +}; + +std::vector<TestScenario> CreateTestScenarios() { + std::vector<TestScenario> scenarios; std::vector<TString> credentials_types; std::vector<TString> messages; - - credentials_types.push_back(kInsecureCredentialsType); - auto sec_list = GetCredentialsProvider()->GetSecureCredentialsTypeList(); - for (auto sec = sec_list.begin(); sec != sec_list.end(); sec++) { - credentials_types.push_back(*sec); - } - - messages.push_back("🖖"); - for (size_t k = 1; k < GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH / 1024; k *= 32) { + + credentials_types.push_back(kInsecureCredentialsType); + auto sec_list = GetCredentialsProvider()->GetSecureCredentialsTypeList(); + for (auto sec = sec_list.begin(); sec != sec_list.end(); sec++) { + credentials_types.push_back(*sec); + } + + messages.push_back("🖖"); + for (size_t k = 1; k < GRPC_DEFAULT_MAX_RECV_MESSAGE_LENGTH / 1024; k *= 32) { TString big_msg; - for (size_t i = 0; i < k * 1024; ++i) { - char c = 'a' + (i % 26); - big_msg += c; - } - messages.push_back(big_msg); - } - for (auto cred = credentials_types.begin(); cred != credentials_types.end(); - ++cred) { - for (auto msg = messages.begin(); msg != messages.end(); msg++) { - scenarios.emplace_back(*cred, *msg); - } - } - - return scenarios; -} - -INSTANTIATE_TEST_SUITE_P(FlakyNetworkTest, FlakyNetworkTest, - ::testing::ValuesIn(CreateTestScenarios())); - -// Network interface connected to server flaps -TEST_P(FlakyNetworkTest, NetworkTransition) { - const int kKeepAliveTimeMs = 1000; - const int kKeepAliveTimeoutMs = 1000; - ChannelArguments args; - args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); - args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); - args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); - args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); - - auto channel = BuildChannel("pick_first", args); - auto stub = BuildStub(channel); - // Channel should be in READY state after we send an RPC - EXPECT_TRUE(SendRpc(stub)); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - - std::atomic_bool shutdown{false}; - std::thread sender = std::thread([this, &stub, &shutdown]() { - while (true) { - if (shutdown.load()) { - return; - } - SendRpc(stub); - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - } - }); - - // bring down network - NetworkDown(); - EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - // bring network interface back up - InterfaceUp(); - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - // Restore DNS entry for server - DNSUp(); - EXPECT_TRUE(WaitForChannelReady(channel.get())); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - shutdown.store(true); - sender.join(); -} - -// Traffic to server server is blackholed temporarily with keepalives enabled -TEST_P(FlakyNetworkTest, ServerUnreachableWithKeepalive) { - const int kKeepAliveTimeMs = 1000; - const int kKeepAliveTimeoutMs = 1000; - const int kReconnectBackoffMs = 1000; - ChannelArguments args; - args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); - args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); - args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); - args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); - // max time for a connection attempt - args.SetInt(GRPC_ARG_MIN_RECONNECT_BACKOFF_MS, kReconnectBackoffMs); - // max time between reconnect attempts - args.SetInt(GRPC_ARG_MAX_RECONNECT_BACKOFF_MS, kReconnectBackoffMs); - - gpr_log(GPR_DEBUG, "FlakyNetworkTest.ServerUnreachableWithKeepalive start"); - auto channel = BuildChannel("pick_first", args); - auto stub = BuildStub(channel); - // Channel should be in READY state after we send an RPC - EXPECT_TRUE(SendRpc(stub)); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - - std::atomic_bool shutdown{false}; - std::thread sender = std::thread([this, &stub, &shutdown]() { - while (true) { - if (shutdown.load()) { - return; - } - SendRpc(stub); - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - } - }); - - // break network connectivity - gpr_log(GPR_DEBUG, "Adding iptables rule to drop packets"); - DropPackets(); - std::this_thread::sleep_for(std::chrono::milliseconds(10000)); - EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - // bring network interface back up - RestoreNetwork(); - gpr_log(GPR_DEBUG, "Removed iptables rule to drop packets"); - EXPECT_TRUE(WaitForChannelReady(channel.get())); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - shutdown.store(true); - sender.join(); - gpr_log(GPR_DEBUG, "FlakyNetworkTest.ServerUnreachableWithKeepalive end"); -} - -// -// Traffic to server server is blackholed temporarily with keepalives disabled -TEST_P(FlakyNetworkTest, ServerUnreachableNoKeepalive) { - auto channel = BuildChannel("pick_first", ChannelArguments()); - auto stub = BuildStub(channel); - // Channel should be in READY state after we send an RPC - EXPECT_TRUE(SendRpc(stub)); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - - // break network connectivity - DropPackets(); - - std::thread sender = std::thread([this, &stub]() { - // RPC with deadline should timeout - EXPECT_FALSE(SendRpc(stub, /*timeout_ms=*/500, /*wait_for_ready=*/true)); - // RPC without deadline forever until call finishes - EXPECT_TRUE(SendRpc(stub, /*timeout_ms=*/0, /*wait_for_ready=*/true)); - }); - - std::this_thread::sleep_for(std::chrono::milliseconds(2000)); - // bring network interface back up - RestoreNetwork(); - - // wait for RPC to finish - sender.join(); -} - -// Send RPCs over a flaky network connection -TEST_P(FlakyNetworkTest, FlakyNetwork) { - const int kKeepAliveTimeMs = 1000; - const int kKeepAliveTimeoutMs = 1000; - const int kMessageCount = 100; - ChannelArguments args; - args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); - args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); - args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); - args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); - - auto channel = BuildChannel("pick_first", args); - auto stub = BuildStub(channel); - // Channel should be in READY state after we send an RPC - EXPECT_TRUE(SendRpc(stub)); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - - // simulate flaky network (packet loss, corruption and delays) - FlakeNetwork(); - for (int i = 0; i < kMessageCount; ++i) { - SendRpc(stub); - } - // remove network flakiness - UnflakeNetwork(); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); -} - -// Server is shutdown gracefully and restarted. Client keepalives are enabled -TEST_P(FlakyNetworkTest, ServerRestartKeepaliveEnabled) { - const int kKeepAliveTimeMs = 1000; - const int kKeepAliveTimeoutMs = 1000; - ChannelArguments args; - args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); - args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); - args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); - args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); - - auto channel = BuildChannel("pick_first", args); - auto stub = BuildStub(channel); - // Channel should be in READY state after we send an RPC - EXPECT_TRUE(SendRpc(stub)); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - - // server goes down, client should detect server going down and calls should - // fail - StopServer(); - EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - EXPECT_FALSE(SendRpc(stub)); - - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - - // server restarts, calls succeed - StartServer(); - EXPECT_TRUE(WaitForChannelReady(channel.get())); - // EXPECT_TRUE(SendRpc(stub)); -} - -// Server is shutdown gracefully and restarted. Client keepalives are enabled -TEST_P(FlakyNetworkTest, ServerRestartKeepaliveDisabled) { - auto channel = BuildChannel("pick_first", ChannelArguments()); - auto stub = BuildStub(channel); - // Channel should be in READY state after we send an RPC - EXPECT_TRUE(SendRpc(stub)); - EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); - - // server sends GOAWAY when it's shutdown, so client attempts to reconnect - StopServer(); - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - - EXPECT_TRUE(WaitForChannelNotReady(channel.get())); - - std::this_thread::sleep_for(std::chrono::milliseconds(1000)); - - // server restarts, calls succeed - StartServer(); - EXPECT_TRUE(WaitForChannelReady(channel.get())); -} - -} // namespace -} // namespace testing -} // namespace grpc -#endif // GPR_LINUX - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); + for (size_t i = 0; i < k * 1024; ++i) { + char c = 'a' + (i % 26); + big_msg += c; + } + messages.push_back(big_msg); + } + for (auto cred = credentials_types.begin(); cred != credentials_types.end(); + ++cred) { + for (auto msg = messages.begin(); msg != messages.end(); msg++) { + scenarios.emplace_back(*cred, *msg); + } + } + + return scenarios; +} + +INSTANTIATE_TEST_SUITE_P(FlakyNetworkTest, FlakyNetworkTest, + ::testing::ValuesIn(CreateTestScenarios())); + +// Network interface connected to server flaps +TEST_P(FlakyNetworkTest, NetworkTransition) { + const int kKeepAliveTimeMs = 1000; + const int kKeepAliveTimeoutMs = 1000; + ChannelArguments args; + args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); + args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); + args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); + args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); + + auto channel = BuildChannel("pick_first", args); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + EXPECT_TRUE(SendRpc(stub)); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + std::atomic_bool shutdown{false}; + std::thread sender = std::thread([this, &stub, &shutdown]() { + while (true) { + if (shutdown.load()) { + return; + } + SendRpc(stub); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + } + }); + + // bring down network + NetworkDown(); + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + // bring network interface back up + InterfaceUp(); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + // Restore DNS entry for server + DNSUp(); + EXPECT_TRUE(WaitForChannelReady(channel.get())); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + shutdown.store(true); + sender.join(); +} + +// Traffic to server server is blackholed temporarily with keepalives enabled +TEST_P(FlakyNetworkTest, ServerUnreachableWithKeepalive) { + const int kKeepAliveTimeMs = 1000; + const int kKeepAliveTimeoutMs = 1000; + const int kReconnectBackoffMs = 1000; + ChannelArguments args; + args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); + args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); + args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); + args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); + // max time for a connection attempt + args.SetInt(GRPC_ARG_MIN_RECONNECT_BACKOFF_MS, kReconnectBackoffMs); + // max time between reconnect attempts + args.SetInt(GRPC_ARG_MAX_RECONNECT_BACKOFF_MS, kReconnectBackoffMs); + + gpr_log(GPR_DEBUG, "FlakyNetworkTest.ServerUnreachableWithKeepalive start"); + auto channel = BuildChannel("pick_first", args); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + EXPECT_TRUE(SendRpc(stub)); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + std::atomic_bool shutdown{false}; + std::thread sender = std::thread([this, &stub, &shutdown]() { + while (true) { + if (shutdown.load()) { + return; + } + SendRpc(stub); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + } + }); + + // break network connectivity + gpr_log(GPR_DEBUG, "Adding iptables rule to drop packets"); + DropPackets(); + std::this_thread::sleep_for(std::chrono::milliseconds(10000)); + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + // bring network interface back up + RestoreNetwork(); + gpr_log(GPR_DEBUG, "Removed iptables rule to drop packets"); + EXPECT_TRUE(WaitForChannelReady(channel.get())); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + shutdown.store(true); + sender.join(); + gpr_log(GPR_DEBUG, "FlakyNetworkTest.ServerUnreachableWithKeepalive end"); +} + +// +// Traffic to server server is blackholed temporarily with keepalives disabled +TEST_P(FlakyNetworkTest, ServerUnreachableNoKeepalive) { + auto channel = BuildChannel("pick_first", ChannelArguments()); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + EXPECT_TRUE(SendRpc(stub)); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + // break network connectivity + DropPackets(); + + std::thread sender = std::thread([this, &stub]() { + // RPC with deadline should timeout + EXPECT_FALSE(SendRpc(stub, /*timeout_ms=*/500, /*wait_for_ready=*/true)); + // RPC without deadline forever until call finishes + EXPECT_TRUE(SendRpc(stub, /*timeout_ms=*/0, /*wait_for_ready=*/true)); + }); + + std::this_thread::sleep_for(std::chrono::milliseconds(2000)); + // bring network interface back up + RestoreNetwork(); + + // wait for RPC to finish + sender.join(); +} + +// Send RPCs over a flaky network connection +TEST_P(FlakyNetworkTest, FlakyNetwork) { + const int kKeepAliveTimeMs = 1000; + const int kKeepAliveTimeoutMs = 1000; + const int kMessageCount = 100; + ChannelArguments args; + args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); + args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); + args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); + args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); + + auto channel = BuildChannel("pick_first", args); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + EXPECT_TRUE(SendRpc(stub)); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + // simulate flaky network (packet loss, corruption and delays) + FlakeNetwork(); + for (int i = 0; i < kMessageCount; ++i) { + SendRpc(stub); + } + // remove network flakiness + UnflakeNetwork(); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); +} + +// Server is shutdown gracefully and restarted. Client keepalives are enabled +TEST_P(FlakyNetworkTest, ServerRestartKeepaliveEnabled) { + const int kKeepAliveTimeMs = 1000; + const int kKeepAliveTimeoutMs = 1000; + ChannelArguments args; + args.SetInt(GRPC_ARG_KEEPALIVE_TIME_MS, kKeepAliveTimeMs); + args.SetInt(GRPC_ARG_KEEPALIVE_TIMEOUT_MS, kKeepAliveTimeoutMs); + args.SetInt(GRPC_ARG_KEEPALIVE_PERMIT_WITHOUT_CALLS, 1); + args.SetInt(GRPC_ARG_HTTP2_MAX_PINGS_WITHOUT_DATA, 0); + + auto channel = BuildChannel("pick_first", args); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + EXPECT_TRUE(SendRpc(stub)); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + // server goes down, client should detect server going down and calls should + // fail + StopServer(); + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + EXPECT_FALSE(SendRpc(stub)); + + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + + // server restarts, calls succeed + StartServer(); + EXPECT_TRUE(WaitForChannelReady(channel.get())); + // EXPECT_TRUE(SendRpc(stub)); +} + +// Server is shutdown gracefully and restarted. Client keepalives are enabled +TEST_P(FlakyNetworkTest, ServerRestartKeepaliveDisabled) { + auto channel = BuildChannel("pick_first", ChannelArguments()); + auto stub = BuildStub(channel); + // Channel should be in READY state after we send an RPC + EXPECT_TRUE(SendRpc(stub)); + EXPECT_EQ(channel->GetState(false), GRPC_CHANNEL_READY); + + // server sends GOAWAY when it's shutdown, so client attempts to reconnect + StopServer(); + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + + EXPECT_TRUE(WaitForChannelNotReady(channel.get())); + + std::this_thread::sleep_for(std::chrono::milliseconds(1000)); + + // server restarts, calls succeed + StartServer(); + EXPECT_TRUE(WaitForChannelReady(channel.get())); +} + +} // namespace +} // namespace testing +} // namespace grpc +#endif // GPR_LINUX + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); grpc::testing::TestEnvironment env(argc, argv); - auto result = RUN_ALL_TESTS(); - return result; -} + auto result = RUN_ALL_TESTS(); + return result; +} diff --git a/contrib/libs/grpc/test/cpp/end2end/message_allocator_end2end_test.cc b/contrib/libs/grpc/test/cpp/end2end/message_allocator_end2end_test.cc index 4bf755206e3..11e6f5a8321 100644 --- a/contrib/libs/grpc/test/cpp/end2end/message_allocator_end2end_test.cc +++ b/contrib/libs/grpc/test/cpp/end2end/message_allocator_end2end_test.cc @@ -1,151 +1,151 @@ -/* - * - * Copyright 2019 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 <algorithm> +/* + * + * Copyright 2019 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 <algorithm> #include <atomic> -#include <condition_variable> -#include <functional> -#include <memory> -#include <mutex> -#include <sstream> -#include <thread> - -#include <google/protobuf/arena.h> - -#include <grpc/impl/codegen/log.h> -#include <gtest/gtest.h> - -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> -#include <grpcpp/support/client_callback.h> -#include <grpcpp/support/message_allocator.h> - -#include "src/core/lib/iomgr/iomgr.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/util/test_credentials_provider.h" - -// MAYBE_SKIP_TEST is a macro to determine if this particular test configuration -// should be skipped based on a decision made at SetUp time. In particular, any -// callback tests can only be run if the iomgr can run in the background or if -// the transport is in-process. -#define MAYBE_SKIP_TEST \ - do { \ - if (do_not_test_) { \ - return; \ - } \ - } while (0) - -namespace grpc { -namespace testing { -namespace { - -class CallbackTestServiceImpl - : public EchoTestService::ExperimentalCallbackService { - public: - explicit CallbackTestServiceImpl() {} - - void SetAllocatorMutator( - std::function<void(experimental::RpcAllocatorState* allocator_state, - const EchoRequest* req, EchoResponse* resp)> - mutator) { - allocator_mutator_ = mutator; - } - - experimental::ServerUnaryReactor* Echo( - experimental::CallbackServerContext* context, const EchoRequest* request, - EchoResponse* response) override { - response->set_message(request->message()); - if (allocator_mutator_) { - allocator_mutator_(context->GetRpcAllocatorState(), request, response); - } - auto* reactor = context->DefaultReactor(); - reactor->Finish(Status::OK); - return reactor; - } - - private: - std::function<void(experimental::RpcAllocatorState* allocator_state, - const EchoRequest* req, EchoResponse* resp)> - allocator_mutator_; -}; - -enum class Protocol { INPROC, TCP }; - -class TestScenario { - public: +#include <condition_variable> +#include <functional> +#include <memory> +#include <mutex> +#include <sstream> +#include <thread> + +#include <google/protobuf/arena.h> + +#include <grpc/impl/codegen/log.h> +#include <gtest/gtest.h> + +#include <grpcpp/channel.h> +#include <grpcpp/client_context.h> +#include <grpcpp/create_channel.h> +#include <grpcpp/server.h> +#include <grpcpp/server_builder.h> +#include <grpcpp/server_context.h> +#include <grpcpp/support/client_callback.h> +#include <grpcpp/support/message_allocator.h> + +#include "src/core/lib/iomgr/iomgr.h" +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/util/test_credentials_provider.h" + +// MAYBE_SKIP_TEST is a macro to determine if this particular test configuration +// should be skipped based on a decision made at SetUp time. In particular, any +// callback tests can only be run if the iomgr can run in the background or if +// the transport is in-process. +#define MAYBE_SKIP_TEST \ + do { \ + if (do_not_test_) { \ + return; \ + } \ + } while (0) + +namespace grpc { +namespace testing { +namespace { + +class CallbackTestServiceImpl + : public EchoTestService::ExperimentalCallbackService { + public: + explicit CallbackTestServiceImpl() {} + + void SetAllocatorMutator( + std::function<void(experimental::RpcAllocatorState* allocator_state, + const EchoRequest* req, EchoResponse* resp)> + mutator) { + allocator_mutator_ = mutator; + } + + experimental::ServerUnaryReactor* Echo( + experimental::CallbackServerContext* context, const EchoRequest* request, + EchoResponse* response) override { + response->set_message(request->message()); + if (allocator_mutator_) { + allocator_mutator_(context->GetRpcAllocatorState(), request, response); + } + auto* reactor = context->DefaultReactor(); + reactor->Finish(Status::OK); + return reactor; + } + + private: + std::function<void(experimental::RpcAllocatorState* allocator_state, + const EchoRequest* req, EchoResponse* resp)> + allocator_mutator_; +}; + +enum class Protocol { INPROC, TCP }; + +class TestScenario { + public: TestScenario(Protocol protocol, const TString& creds_type) - : protocol(protocol), credentials_type(creds_type) {} - void Log() const; - Protocol protocol; + : protocol(protocol), credentials_type(creds_type) {} + void Log() const; + Protocol protocol; const TString credentials_type; -}; - -static std::ostream& operator<<(std::ostream& out, - const TestScenario& scenario) { - return out << "TestScenario{protocol=" - << (scenario.protocol == Protocol::INPROC ? "INPROC" : "TCP") - << "," << scenario.credentials_type << "}"; -} - -void TestScenario::Log() const { - std::ostringstream out; - out << *this; - gpr_log(GPR_INFO, "%s", out.str().c_str()); -} - -class MessageAllocatorEnd2endTestBase - : public ::testing::TestWithParam<TestScenario> { - protected: - MessageAllocatorEnd2endTestBase() { - GetParam().Log(); - if (GetParam().protocol == Protocol::TCP) { - if (!grpc_iomgr_run_in_background()) { - do_not_test_ = true; - return; - } - } - } - - ~MessageAllocatorEnd2endTestBase() = default; - - void CreateServer( - experimental::MessageAllocator<EchoRequest, EchoResponse>* allocator) { - ServerBuilder builder; - - auto server_creds = GetCredentialsProvider()->GetServerCredentials( - GetParam().credentials_type); - if (GetParam().protocol == Protocol::TCP) { - picked_port_ = grpc_pick_unused_port_or_die(); - server_address_ << "localhost:" << picked_port_; - builder.AddListeningPort(server_address_.str(), server_creds); - } - callback_service_.SetMessageAllocatorFor_Echo(allocator); - builder.RegisterService(&callback_service_); - - server_ = builder.BuildAndStart(); - } - +}; + +static std::ostream& operator<<(std::ostream& out, + const TestScenario& scenario) { + return out << "TestScenario{protocol=" + << (scenario.protocol == Protocol::INPROC ? "INPROC" : "TCP") + << "," << scenario.credentials_type << "}"; +} + +void TestScenario::Log() const { + std::ostringstream out; + out << *this; + gpr_log(GPR_INFO, "%s", out.str().c_str()); +} + +class MessageAllocatorEnd2endTestBase + : public ::testing::TestWithParam<TestScenario> { + protected: + MessageAllocatorEnd2endTestBase() { + GetParam().Log(); + if (GetParam().protocol == Protocol::TCP) { + if (!grpc_iomgr_run_in_background()) { + do_not_test_ = true; + return; + } + } + } + + ~MessageAllocatorEnd2endTestBase() = default; + + void CreateServer( + experimental::MessageAllocator<EchoRequest, EchoResponse>* allocator) { + ServerBuilder builder; + + auto server_creds = GetCredentialsProvider()->GetServerCredentials( + GetParam().credentials_type); + if (GetParam().protocol == Protocol::TCP) { + picked_port_ = grpc_pick_unused_port_or_die(); + server_address_ << "localhost:" << picked_port_; + builder.AddListeningPort(server_address_.str(), server_creds); + } + callback_service_.SetMessageAllocatorFor_Echo(allocator); + builder.RegisterService(&callback_service_); + + server_ = builder.BuildAndStart(); + } + void DestroyServer() { if (server_) { server_->Shutdown(); @@ -153,286 +153,286 @@ class MessageAllocatorEnd2endTestBase } } - void ResetStub() { - ChannelArguments args; - auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( - GetParam().credentials_type, &args); - switch (GetParam().protocol) { - case Protocol::TCP: - channel_ = ::grpc::CreateCustomChannel(server_address_.str(), - channel_creds, args); - break; - case Protocol::INPROC: - channel_ = server_->InProcessChannel(args); - break; - default: - assert(false); - } - stub_ = EchoTestService::NewStub(channel_); - } - - void TearDown() override { + void ResetStub() { + ChannelArguments args; + auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( + GetParam().credentials_type, &args); + switch (GetParam().protocol) { + case Protocol::TCP: + channel_ = ::grpc::CreateCustomChannel(server_address_.str(), + channel_creds, args); + break; + case Protocol::INPROC: + channel_ = server_->InProcessChannel(args); + break; + default: + assert(false); + } + stub_ = EchoTestService::NewStub(channel_); + } + + void TearDown() override { DestroyServer(); - if (picked_port_ > 0) { - grpc_recycle_unused_port(picked_port_); - } - } - - void SendRpcs(int num_rpcs) { + if (picked_port_ > 0) { + grpc_recycle_unused_port(picked_port_); + } + } + + void SendRpcs(int num_rpcs) { TString test_string(""); - for (int i = 0; i < num_rpcs; i++) { - EchoRequest request; - EchoResponse response; - ClientContext cli_ctx; - + for (int i = 0; i < num_rpcs; i++) { + EchoRequest request; + EchoResponse response; + ClientContext cli_ctx; + test_string += TString(1024, 'x'); - request.set_message(test_string); + request.set_message(test_string); TString val; - cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP); - - std::mutex mu; - std::condition_variable cv; - bool done = false; - stub_->experimental_async()->Echo( - &cli_ctx, &request, &response, - [&request, &response, &done, &mu, &cv, val](Status s) { - GPR_ASSERT(s.ok()); - - EXPECT_EQ(request.message(), response.message()); - std::lock_guard<std::mutex> l(mu); - done = true; - cv.notify_one(); - }); - std::unique_lock<std::mutex> l(mu); - while (!done) { - cv.wait(l); - } - } - } - - bool do_not_test_{false}; - int picked_port_{0}; - std::shared_ptr<Channel> channel_; - std::unique_ptr<EchoTestService::Stub> stub_; - CallbackTestServiceImpl callback_service_; - std::unique_ptr<Server> server_; - std::ostringstream server_address_; -}; - -class NullAllocatorTest : public MessageAllocatorEnd2endTestBase {}; - -TEST_P(NullAllocatorTest, SimpleRpc) { - MAYBE_SKIP_TEST; - CreateServer(nullptr); - ResetStub(); - SendRpcs(1); -} - -class SimpleAllocatorTest : public MessageAllocatorEnd2endTestBase { - public: - class SimpleAllocator - : public experimental::MessageAllocator<EchoRequest, EchoResponse> { - public: - class MessageHolderImpl - : public experimental::MessageHolder<EchoRequest, EchoResponse> { - public: + cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP); + + std::mutex mu; + std::condition_variable cv; + bool done = false; + stub_->experimental_async()->Echo( + &cli_ctx, &request, &response, + [&request, &response, &done, &mu, &cv, val](Status s) { + GPR_ASSERT(s.ok()); + + EXPECT_EQ(request.message(), response.message()); + std::lock_guard<std::mutex> l(mu); + done = true; + cv.notify_one(); + }); + std::unique_lock<std::mutex> l(mu); + while (!done) { + cv.wait(l); + } + } + } + + bool do_not_test_{false}; + int picked_port_{0}; + std::shared_ptr<Channel> channel_; + std::unique_ptr<EchoTestService::Stub> stub_; + CallbackTestServiceImpl callback_service_; + std::unique_ptr<Server> server_; + std::ostringstream server_address_; +}; + +class NullAllocatorTest : public MessageAllocatorEnd2endTestBase {}; + +TEST_P(NullAllocatorTest, SimpleRpc) { + MAYBE_SKIP_TEST; + CreateServer(nullptr); + ResetStub(); + SendRpcs(1); +} + +class SimpleAllocatorTest : public MessageAllocatorEnd2endTestBase { + public: + class SimpleAllocator + : public experimental::MessageAllocator<EchoRequest, EchoResponse> { + public: + class MessageHolderImpl + : public experimental::MessageHolder<EchoRequest, EchoResponse> { + public: MessageHolderImpl(std::atomic_int* request_deallocation_count, std::atomic_int* messages_deallocation_count) - : request_deallocation_count_(request_deallocation_count), - messages_deallocation_count_(messages_deallocation_count) { - set_request(new EchoRequest); - set_response(new EchoResponse); - } - void Release() override { - (*messages_deallocation_count_)++; - delete request(); - delete response(); - delete this; - } - void FreeRequest() override { - (*request_deallocation_count_)++; - delete request(); - set_request(nullptr); - } - - EchoRequest* ReleaseRequest() { - auto* ret = request(); - set_request(nullptr); - return ret; - } - - private: + : request_deallocation_count_(request_deallocation_count), + messages_deallocation_count_(messages_deallocation_count) { + set_request(new EchoRequest); + set_response(new EchoResponse); + } + void Release() override { + (*messages_deallocation_count_)++; + delete request(); + delete response(); + delete this; + } + void FreeRequest() override { + (*request_deallocation_count_)++; + delete request(); + set_request(nullptr); + } + + EchoRequest* ReleaseRequest() { + auto* ret = request(); + set_request(nullptr); + return ret; + } + + private: std::atomic_int* const request_deallocation_count_; std::atomic_int* const messages_deallocation_count_; - }; - experimental::MessageHolder<EchoRequest, EchoResponse>* AllocateMessages() - override { - allocation_count++; - return new MessageHolderImpl(&request_deallocation_count, - &messages_deallocation_count); - } - int allocation_count = 0; + }; + experimental::MessageHolder<EchoRequest, EchoResponse>* AllocateMessages() + override { + allocation_count++; + return new MessageHolderImpl(&request_deallocation_count, + &messages_deallocation_count); + } + int allocation_count = 0; std::atomic_int request_deallocation_count{0}; std::atomic_int messages_deallocation_count{0}; - }; -}; - -TEST_P(SimpleAllocatorTest, SimpleRpc) { - MAYBE_SKIP_TEST; - const int kRpcCount = 10; - std::unique_ptr<SimpleAllocator> allocator(new SimpleAllocator); - CreateServer(allocator.get()); - ResetStub(); - SendRpcs(kRpcCount); + }; +}; + +TEST_P(SimpleAllocatorTest, SimpleRpc) { + MAYBE_SKIP_TEST; + const int kRpcCount = 10; + std::unique_ptr<SimpleAllocator> allocator(new SimpleAllocator); + CreateServer(allocator.get()); + ResetStub(); + SendRpcs(kRpcCount); // messages_deallocaton_count is updated in Release after server side OnDone. // Destroy server to make sure it has been updated. DestroyServer(); - EXPECT_EQ(kRpcCount, allocator->allocation_count); - EXPECT_EQ(kRpcCount, allocator->messages_deallocation_count); - EXPECT_EQ(0, allocator->request_deallocation_count); -} - -TEST_P(SimpleAllocatorTest, RpcWithEarlyFreeRequest) { - MAYBE_SKIP_TEST; - const int kRpcCount = 10; - std::unique_ptr<SimpleAllocator> allocator(new SimpleAllocator); - auto mutator = [](experimental::RpcAllocatorState* allocator_state, - const EchoRequest* req, EchoResponse* resp) { - auto* info = - static_cast<SimpleAllocator::MessageHolderImpl*>(allocator_state); - EXPECT_EQ(req, info->request()); - EXPECT_EQ(resp, info->response()); - allocator_state->FreeRequest(); - EXPECT_EQ(nullptr, info->request()); - }; - callback_service_.SetAllocatorMutator(mutator); - CreateServer(allocator.get()); - ResetStub(); - SendRpcs(kRpcCount); + EXPECT_EQ(kRpcCount, allocator->allocation_count); + EXPECT_EQ(kRpcCount, allocator->messages_deallocation_count); + EXPECT_EQ(0, allocator->request_deallocation_count); +} + +TEST_P(SimpleAllocatorTest, RpcWithEarlyFreeRequest) { + MAYBE_SKIP_TEST; + const int kRpcCount = 10; + std::unique_ptr<SimpleAllocator> allocator(new SimpleAllocator); + auto mutator = [](experimental::RpcAllocatorState* allocator_state, + const EchoRequest* req, EchoResponse* resp) { + auto* info = + static_cast<SimpleAllocator::MessageHolderImpl*>(allocator_state); + EXPECT_EQ(req, info->request()); + EXPECT_EQ(resp, info->response()); + allocator_state->FreeRequest(); + EXPECT_EQ(nullptr, info->request()); + }; + callback_service_.SetAllocatorMutator(mutator); + CreateServer(allocator.get()); + ResetStub(); + SendRpcs(kRpcCount); // messages_deallocaton_count is updated in Release after server side OnDone. // Destroy server to make sure it has been updated. DestroyServer(); - EXPECT_EQ(kRpcCount, allocator->allocation_count); - EXPECT_EQ(kRpcCount, allocator->messages_deallocation_count); - EXPECT_EQ(kRpcCount, allocator->request_deallocation_count); -} - -TEST_P(SimpleAllocatorTest, RpcWithReleaseRequest) { - MAYBE_SKIP_TEST; - const int kRpcCount = 10; - std::unique_ptr<SimpleAllocator> allocator(new SimpleAllocator); - std::vector<EchoRequest*> released_requests; - auto mutator = [&released_requests]( - experimental::RpcAllocatorState* allocator_state, - const EchoRequest* req, EchoResponse* resp) { - auto* info = - static_cast<SimpleAllocator::MessageHolderImpl*>(allocator_state); - EXPECT_EQ(req, info->request()); - EXPECT_EQ(resp, info->response()); - released_requests.push_back(info->ReleaseRequest()); - EXPECT_EQ(nullptr, info->request()); - }; - callback_service_.SetAllocatorMutator(mutator); - CreateServer(allocator.get()); - ResetStub(); - SendRpcs(kRpcCount); + EXPECT_EQ(kRpcCount, allocator->allocation_count); + EXPECT_EQ(kRpcCount, allocator->messages_deallocation_count); + EXPECT_EQ(kRpcCount, allocator->request_deallocation_count); +} + +TEST_P(SimpleAllocatorTest, RpcWithReleaseRequest) { + MAYBE_SKIP_TEST; + const int kRpcCount = 10; + std::unique_ptr<SimpleAllocator> allocator(new SimpleAllocator); + std::vector<EchoRequest*> released_requests; + auto mutator = [&released_requests]( + experimental::RpcAllocatorState* allocator_state, + const EchoRequest* req, EchoResponse* resp) { + auto* info = + static_cast<SimpleAllocator::MessageHolderImpl*>(allocator_state); + EXPECT_EQ(req, info->request()); + EXPECT_EQ(resp, info->response()); + released_requests.push_back(info->ReleaseRequest()); + EXPECT_EQ(nullptr, info->request()); + }; + callback_service_.SetAllocatorMutator(mutator); + CreateServer(allocator.get()); + ResetStub(); + SendRpcs(kRpcCount); // messages_deallocaton_count is updated in Release after server side OnDone. // Destroy server to make sure it has been updated. DestroyServer(); - EXPECT_EQ(kRpcCount, allocator->allocation_count); - EXPECT_EQ(kRpcCount, allocator->messages_deallocation_count); - EXPECT_EQ(0, allocator->request_deallocation_count); - EXPECT_EQ(static_cast<unsigned>(kRpcCount), released_requests.size()); - for (auto* req : released_requests) { - delete req; - } -} - -class ArenaAllocatorTest : public MessageAllocatorEnd2endTestBase { - public: - class ArenaAllocator - : public experimental::MessageAllocator<EchoRequest, EchoResponse> { - public: - class MessageHolderImpl - : public experimental::MessageHolder<EchoRequest, EchoResponse> { - public: - MessageHolderImpl() { - set_request( - google::protobuf::Arena::CreateMessage<EchoRequest>(&arena_)); - set_response( - google::protobuf::Arena::CreateMessage<EchoResponse>(&arena_)); - } - void Release() override { delete this; } - void FreeRequest() override { GPR_ASSERT(0); } - - private: - google::protobuf::Arena arena_; - }; - experimental::MessageHolder<EchoRequest, EchoResponse>* AllocateMessages() - override { - allocation_count++; - return new MessageHolderImpl; - } - int allocation_count = 0; - }; -}; - -TEST_P(ArenaAllocatorTest, SimpleRpc) { - MAYBE_SKIP_TEST; - const int kRpcCount = 10; - std::unique_ptr<ArenaAllocator> allocator(new ArenaAllocator); - CreateServer(allocator.get()); - ResetStub(); - SendRpcs(kRpcCount); - EXPECT_EQ(kRpcCount, allocator->allocation_count); -} - -std::vector<TestScenario> CreateTestScenarios(bool test_insecure) { - std::vector<TestScenario> scenarios; + EXPECT_EQ(kRpcCount, allocator->allocation_count); + EXPECT_EQ(kRpcCount, allocator->messages_deallocation_count); + EXPECT_EQ(0, allocator->request_deallocation_count); + EXPECT_EQ(static_cast<unsigned>(kRpcCount), released_requests.size()); + for (auto* req : released_requests) { + delete req; + } +} + +class ArenaAllocatorTest : public MessageAllocatorEnd2endTestBase { + public: + class ArenaAllocator + : public experimental::MessageAllocator<EchoRequest, EchoResponse> { + public: + class MessageHolderImpl + : public experimental::MessageHolder<EchoRequest, EchoResponse> { + public: + MessageHolderImpl() { + set_request( + google::protobuf::Arena::CreateMessage<EchoRequest>(&arena_)); + set_response( + google::protobuf::Arena::CreateMessage<EchoResponse>(&arena_)); + } + void Release() override { delete this; } + void FreeRequest() override { GPR_ASSERT(0); } + + private: + google::protobuf::Arena arena_; + }; + experimental::MessageHolder<EchoRequest, EchoResponse>* AllocateMessages() + override { + allocation_count++; + return new MessageHolderImpl; + } + int allocation_count = 0; + }; +}; + +TEST_P(ArenaAllocatorTest, SimpleRpc) { + MAYBE_SKIP_TEST; + const int kRpcCount = 10; + std::unique_ptr<ArenaAllocator> allocator(new ArenaAllocator); + CreateServer(allocator.get()); + ResetStub(); + SendRpcs(kRpcCount); + EXPECT_EQ(kRpcCount, allocator->allocation_count); +} + +std::vector<TestScenario> CreateTestScenarios(bool test_insecure) { + std::vector<TestScenario> scenarios; std::vector<TString> credentials_types{ - GetCredentialsProvider()->GetSecureCredentialsTypeList()}; - auto insec_ok = [] { - // Only allow insecure credentials type when it is registered with the - // provider. User may create providers that do not have insecure. - return GetCredentialsProvider()->GetChannelCredentials( - kInsecureCredentialsType, nullptr) != nullptr; - }; - if (test_insecure && insec_ok()) { - credentials_types.push_back(kInsecureCredentialsType); - } - GPR_ASSERT(!credentials_types.empty()); - - Protocol parr[]{Protocol::INPROC, Protocol::TCP}; - for (Protocol p : parr) { - for (const auto& cred : credentials_types) { - // TODO(vjpai): Test inproc with secure credentials when feasible - if (p == Protocol::INPROC && - (cred != kInsecureCredentialsType || !insec_ok())) { - continue; - } - scenarios.emplace_back(p, cred); - } - } - return scenarios; -} - -INSTANTIATE_TEST_SUITE_P(NullAllocatorTest, NullAllocatorTest, - ::testing::ValuesIn(CreateTestScenarios(true))); -INSTANTIATE_TEST_SUITE_P(SimpleAllocatorTest, SimpleAllocatorTest, - ::testing::ValuesIn(CreateTestScenarios(true))); -INSTANTIATE_TEST_SUITE_P(ArenaAllocatorTest, ArenaAllocatorTest, - ::testing::ValuesIn(CreateTestScenarios(true))); - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - // The grpc_init is to cover the MAYBE_SKIP_TEST. - grpc_init(); - ::testing::InitGoogleTest(&argc, argv); - int ret = RUN_ALL_TESTS(); - grpc_shutdown(); - return ret; -} + GetCredentialsProvider()->GetSecureCredentialsTypeList()}; + auto insec_ok = [] { + // Only allow insecure credentials type when it is registered with the + // provider. User may create providers that do not have insecure. + return GetCredentialsProvider()->GetChannelCredentials( + kInsecureCredentialsType, nullptr) != nullptr; + }; + if (test_insecure && insec_ok()) { + credentials_types.push_back(kInsecureCredentialsType); + } + GPR_ASSERT(!credentials_types.empty()); + + Protocol parr[]{Protocol::INPROC, Protocol::TCP}; + for (Protocol p : parr) { + for (const auto& cred : credentials_types) { + // TODO(vjpai): Test inproc with secure credentials when feasible + if (p == Protocol::INPROC && + (cred != kInsecureCredentialsType || !insec_ok())) { + continue; + } + scenarios.emplace_back(p, cred); + } + } + return scenarios; +} + +INSTANTIATE_TEST_SUITE_P(NullAllocatorTest, NullAllocatorTest, + ::testing::ValuesIn(CreateTestScenarios(true))); +INSTANTIATE_TEST_SUITE_P(SimpleAllocatorTest, SimpleAllocatorTest, + ::testing::ValuesIn(CreateTestScenarios(true))); +INSTANTIATE_TEST_SUITE_P(ArenaAllocatorTest, ArenaAllocatorTest, + ::testing::ValuesIn(CreateTestScenarios(true))); + +} // namespace +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + grpc::testing::TestEnvironment env(argc, argv); + // The grpc_init is to cover the MAYBE_SKIP_TEST. + grpc_init(); + ::testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + grpc_shutdown(); + return ret; +} diff --git a/contrib/libs/grpc/test/cpp/end2end/port_sharing_end2end_test.cc b/contrib/libs/grpc/test/cpp/end2end/port_sharing_end2end_test.cc index b69d1dd2be7..89274f3bb72 100644 --- a/contrib/libs/grpc/test/cpp/end2end/port_sharing_end2end_test.cc +++ b/contrib/libs/grpc/test/cpp/end2end/port_sharing_end2end_test.cc @@ -1,374 +1,374 @@ -/* - * - * Copyright 2019 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/grpc.h> -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/time.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/security/credentials.h> -#include <grpcpp/security/server_credentials.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> -#include <gtest/gtest.h> - -#include <mutex> -#include <thread> - -#include "src/core/lib/gpr/env.h" -#include "src/core/lib/iomgr/endpoint.h" -#include "src/core/lib/iomgr/exec_ctx.h" -#include "src/core/lib/iomgr/pollset.h" -#include "src/core/lib/iomgr/port.h" -#include "src/core/lib/iomgr/tcp_server.h" -#include "src/core/lib/security/credentials/credentials.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/core/util/test_tcp_server.h" -#include "test/cpp/end2end/test_service_impl.h" -#include "test/cpp/util/test_credentials_provider.h" - -#ifdef GRPC_POSIX_SOCKET_TCP_SERVER - -#include "src/core/lib/iomgr/tcp_posix.h" - -namespace grpc { -namespace testing { -namespace { - -class TestScenario { - public: - TestScenario(bool server_port, bool pending_data, +/* + * + * Copyright 2019 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/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/time.h> +#include <grpcpp/channel.h> +#include <grpcpp/client_context.h> +#include <grpcpp/create_channel.h> +#include <grpcpp/security/credentials.h> +#include <grpcpp/security/server_credentials.h> +#include <grpcpp/server.h> +#include <grpcpp/server_builder.h> +#include <grpcpp/server_context.h> +#include <gtest/gtest.h> + +#include <mutex> +#include <thread> + +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/iomgr/endpoint.h" +#include "src/core/lib/iomgr/exec_ctx.h" +#include "src/core/lib/iomgr/pollset.h" +#include "src/core/lib/iomgr/port.h" +#include "src/core/lib/iomgr/tcp_server.h" +#include "src/core/lib/security/credentials/credentials.h" +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/core/util/test_tcp_server.h" +#include "test/cpp/end2end/test_service_impl.h" +#include "test/cpp/util/test_credentials_provider.h" + +#ifdef GRPC_POSIX_SOCKET_TCP_SERVER + +#include "src/core/lib/iomgr/tcp_posix.h" + +namespace grpc { +namespace testing { +namespace { + +class TestScenario { + public: + TestScenario(bool server_port, bool pending_data, const TString& creds_type) - : server_has_port(server_port), - queue_pending_data(pending_data), - credentials_type(creds_type) {} - void Log() const; - // server has its own port or not - bool server_has_port; - // whether tcp server should read some data before handoff - bool queue_pending_data; + : server_has_port(server_port), + queue_pending_data(pending_data), + credentials_type(creds_type) {} + void Log() const; + // server has its own port or not + bool server_has_port; + // whether tcp server should read some data before handoff + bool queue_pending_data; const TString credentials_type; -}; - -static std::ostream& operator<<(std::ostream& out, - const TestScenario& scenario) { - return out << "TestScenario{server_has_port=" - << (scenario.server_has_port ? "true" : "false") - << ", queue_pending_data=" - << (scenario.queue_pending_data ? "true" : "false") - << ", credentials='" << scenario.credentials_type << "'}"; -} - -void TestScenario::Log() const { - std::ostringstream out; - out << *this; - gpr_log(GPR_ERROR, "%s", out.str().c_str()); -} - -// Set up a test tcp server which is in charge of accepting connections and -// handing off the connections as fds. -class TestTcpServer { - public: - TestTcpServer() - : shutdown_(false), - queue_data_(false), - port_(grpc_pick_unused_port_or_die()) { - std::ostringstream server_address; - server_address << "localhost:" << port_; - address_ = server_address.str(); - test_tcp_server_init(&tcp_server_, &TestTcpServer::OnConnect, this); - GRPC_CLOSURE_INIT(&on_fd_released_, &TestTcpServer::OnFdReleased, this, - grpc_schedule_on_exec_ctx); - } - - ~TestTcpServer() { - running_thread_.join(); - test_tcp_server_destroy(&tcp_server_); - grpc_recycle_unused_port(port_); - } - - // Read some data before handing off the connection. - void SetQueueData() { queue_data_ = true; } - - void Start() { - test_tcp_server_start(&tcp_server_, port_); - gpr_log(GPR_INFO, "Test TCP server started at %s", address_.c_str()); - } - +}; + +static std::ostream& operator<<(std::ostream& out, + const TestScenario& scenario) { + return out << "TestScenario{server_has_port=" + << (scenario.server_has_port ? "true" : "false") + << ", queue_pending_data=" + << (scenario.queue_pending_data ? "true" : "false") + << ", credentials='" << scenario.credentials_type << "'}"; +} + +void TestScenario::Log() const { + std::ostringstream out; + out << *this; + gpr_log(GPR_ERROR, "%s", out.str().c_str()); +} + +// Set up a test tcp server which is in charge of accepting connections and +// handing off the connections as fds. +class TestTcpServer { + public: + TestTcpServer() + : shutdown_(false), + queue_data_(false), + port_(grpc_pick_unused_port_or_die()) { + std::ostringstream server_address; + server_address << "localhost:" << port_; + address_ = server_address.str(); + test_tcp_server_init(&tcp_server_, &TestTcpServer::OnConnect, this); + GRPC_CLOSURE_INIT(&on_fd_released_, &TestTcpServer::OnFdReleased, this, + grpc_schedule_on_exec_ctx); + } + + ~TestTcpServer() { + running_thread_.join(); + test_tcp_server_destroy(&tcp_server_); + grpc_recycle_unused_port(port_); + } + + // Read some data before handing off the connection. + void SetQueueData() { queue_data_ = true; } + + void Start() { + test_tcp_server_start(&tcp_server_, port_); + gpr_log(GPR_INFO, "Test TCP server started at %s", address_.c_str()); + } + const TString& address() { return address_; } - - void SetAcceptor( - std::unique_ptr<experimental::ExternalConnectionAcceptor> acceptor) { - connection_acceptor_ = std::move(acceptor); - } - - void Run() { - running_thread_ = std::thread([this]() { - while (true) { - { - std::lock_guard<std::mutex> lock(mu_); - if (shutdown_) { - return; - } - } - test_tcp_server_poll(&tcp_server_, 1); - } - }); - } - - void Shutdown() { - std::lock_guard<std::mutex> lock(mu_); - shutdown_ = true; - } - - static void OnConnect(void* arg, grpc_endpoint* tcp, - grpc_pollset* accepting_pollset, - grpc_tcp_server_acceptor* acceptor) { - auto* self = static_cast<TestTcpServer*>(arg); - self->OnConnect(tcp, accepting_pollset, acceptor); - } - - static void OnFdReleased(void* arg, grpc_error* err) { - auto* self = static_cast<TestTcpServer*>(arg); - self->OnFdReleased(err); - } - - private: - void OnConnect(grpc_endpoint* tcp, grpc_pollset* /*accepting_pollset*/, - grpc_tcp_server_acceptor* acceptor) { + + void SetAcceptor( + std::unique_ptr<experimental::ExternalConnectionAcceptor> acceptor) { + connection_acceptor_ = std::move(acceptor); + } + + void Run() { + running_thread_ = std::thread([this]() { + while (true) { + { + std::lock_guard<std::mutex> lock(mu_); + if (shutdown_) { + return; + } + } + test_tcp_server_poll(&tcp_server_, 1); + } + }); + } + + void Shutdown() { + std::lock_guard<std::mutex> lock(mu_); + shutdown_ = true; + } + + static void OnConnect(void* arg, grpc_endpoint* tcp, + grpc_pollset* accepting_pollset, + grpc_tcp_server_acceptor* acceptor) { + auto* self = static_cast<TestTcpServer*>(arg); + self->OnConnect(tcp, accepting_pollset, acceptor); + } + + static void OnFdReleased(void* arg, grpc_error* err) { + auto* self = static_cast<TestTcpServer*>(arg); + self->OnFdReleased(err); + } + + private: + void OnConnect(grpc_endpoint* tcp, grpc_pollset* /*accepting_pollset*/, + grpc_tcp_server_acceptor* acceptor) { TString peer(grpc_endpoint_get_peer(tcp)); gpr_log(GPR_INFO, "Got incoming connection! from %s", peer.c_str()); - EXPECT_FALSE(acceptor->external_connection); - listener_fd_ = grpc_tcp_server_port_fd( - acceptor->from_server, acceptor->port_index, acceptor->fd_index); - gpr_free(acceptor); - grpc_tcp_destroy_and_release_fd(tcp, &fd_, &on_fd_released_); - } - - void OnFdReleased(grpc_error* err) { - EXPECT_EQ(GRPC_ERROR_NONE, err); - experimental::ExternalConnectionAcceptor::NewConnectionParameters p; - p.listener_fd = listener_fd_; - p.fd = fd_; - if (queue_data_) { - char buf[1024]; - ssize_t read_bytes = 0; - while (read_bytes <= 0) { - read_bytes = read(fd_, buf, 1024); - } - Slice data(buf, read_bytes); - p.read_buffer = ByteBuffer(&data, 1); - } - gpr_log(GPR_INFO, "Handing off fd %d with data size %d from listener fd %d", - fd_, static_cast<int>(p.read_buffer.Length()), listener_fd_); - connection_acceptor_->HandleNewConnection(&p); - } - - std::mutex mu_; - bool shutdown_; - - int listener_fd_ = -1; - int fd_ = -1; - bool queue_data_ = false; - - grpc_closure on_fd_released_; - std::thread running_thread_; - int port_ = -1; + EXPECT_FALSE(acceptor->external_connection); + listener_fd_ = grpc_tcp_server_port_fd( + acceptor->from_server, acceptor->port_index, acceptor->fd_index); + gpr_free(acceptor); + grpc_tcp_destroy_and_release_fd(tcp, &fd_, &on_fd_released_); + } + + void OnFdReleased(grpc_error* err) { + EXPECT_EQ(GRPC_ERROR_NONE, err); + experimental::ExternalConnectionAcceptor::NewConnectionParameters p; + p.listener_fd = listener_fd_; + p.fd = fd_; + if (queue_data_) { + char buf[1024]; + ssize_t read_bytes = 0; + while (read_bytes <= 0) { + read_bytes = read(fd_, buf, 1024); + } + Slice data(buf, read_bytes); + p.read_buffer = ByteBuffer(&data, 1); + } + gpr_log(GPR_INFO, "Handing off fd %d with data size %d from listener fd %d", + fd_, static_cast<int>(p.read_buffer.Length()), listener_fd_); + connection_acceptor_->HandleNewConnection(&p); + } + + std::mutex mu_; + bool shutdown_; + + int listener_fd_ = -1; + int fd_ = -1; + bool queue_data_ = false; + + grpc_closure on_fd_released_; + std::thread running_thread_; + int port_ = -1; TString address_; - std::unique_ptr<experimental::ExternalConnectionAcceptor> - connection_acceptor_; - test_tcp_server tcp_server_; -}; - -class PortSharingEnd2endTest : public ::testing::TestWithParam<TestScenario> { - protected: - PortSharingEnd2endTest() : is_server_started_(false), first_picked_port_(0) { - GetParam().Log(); - } - - void SetUp() override { - if (GetParam().queue_pending_data) { - tcp_server1_.SetQueueData(); - tcp_server2_.SetQueueData(); - } - tcp_server1_.Start(); - tcp_server2_.Start(); - ServerBuilder builder; - if (GetParam().server_has_port) { - int port = grpc_pick_unused_port_or_die(); - first_picked_port_ = port; - server_address_ << "localhost:" << port; - auto creds = GetCredentialsProvider()->GetServerCredentials( - GetParam().credentials_type); - builder.AddListeningPort(server_address_.str(), creds); - gpr_log(GPR_INFO, "gRPC server listening on %s", - server_address_.str().c_str()); - } - auto server_creds = GetCredentialsProvider()->GetServerCredentials( - GetParam().credentials_type); - auto acceptor1 = builder.experimental().AddExternalConnectionAcceptor( - ServerBuilder::experimental_type::ExternalConnectionType::FROM_FD, - server_creds); - tcp_server1_.SetAcceptor(std::move(acceptor1)); - auto acceptor2 = builder.experimental().AddExternalConnectionAcceptor( - ServerBuilder::experimental_type::ExternalConnectionType::FROM_FD, - server_creds); - tcp_server2_.SetAcceptor(std::move(acceptor2)); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - is_server_started_ = true; - - tcp_server1_.Run(); - tcp_server2_.Run(); - } - - void TearDown() override { - tcp_server1_.Shutdown(); - tcp_server2_.Shutdown(); - if (is_server_started_) { - server_->Shutdown(); - } - if (first_picked_port_ > 0) { - grpc_recycle_unused_port(first_picked_port_); - } - } - - void ResetStubs() { - EXPECT_TRUE(is_server_started_); - ChannelArguments args; - args.SetInt(GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL, 1); - auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( - GetParam().credentials_type, &args); - channel_handoff1_ = - CreateCustomChannel(tcp_server1_.address(), channel_creds, args); - stub_handoff1_ = EchoTestService::NewStub(channel_handoff1_); - channel_handoff2_ = - CreateCustomChannel(tcp_server2_.address(), channel_creds, args); - stub_handoff2_ = EchoTestService::NewStub(channel_handoff2_); - if (GetParam().server_has_port) { - ChannelArguments direct_args; - direct_args.SetInt(GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL, 1); - auto direct_creds = GetCredentialsProvider()->GetChannelCredentials( - GetParam().credentials_type, &direct_args); - channel_direct_ = - CreateCustomChannel(server_address_.str(), direct_creds, direct_args); - stub_direct_ = EchoTestService::NewStub(channel_direct_); - } - } - - bool is_server_started_; - // channel/stub to the test tcp server, the connection will be handed to the - // grpc server. - std::shared_ptr<Channel> channel_handoff1_; - std::unique_ptr<EchoTestService::Stub> stub_handoff1_; - std::shared_ptr<Channel> channel_handoff2_; - std::unique_ptr<EchoTestService::Stub> stub_handoff2_; - // channel/stub to talk to the grpc server directly, if applicable. - std::shared_ptr<Channel> channel_direct_; - std::unique_ptr<EchoTestService::Stub> stub_direct_; - std::unique_ptr<Server> server_; - std::ostringstream server_address_; - TestServiceImpl service_; - TestTcpServer tcp_server1_; - TestTcpServer tcp_server2_; - int first_picked_port_; -}; - -static void SendRpc(EchoTestService::Stub* stub, int num_rpcs) { - EchoRequest request; - EchoResponse response; - request.set_message("Hello hello hello hello"); - - for (int i = 0; i < num_rpcs; ++i) { - ClientContext context; - Status s = stub->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); - } -} - -std::vector<TestScenario> CreateTestScenarios() { - std::vector<TestScenario> scenarios; + std::unique_ptr<experimental::ExternalConnectionAcceptor> + connection_acceptor_; + test_tcp_server tcp_server_; +}; + +class PortSharingEnd2endTest : public ::testing::TestWithParam<TestScenario> { + protected: + PortSharingEnd2endTest() : is_server_started_(false), first_picked_port_(0) { + GetParam().Log(); + } + + void SetUp() override { + if (GetParam().queue_pending_data) { + tcp_server1_.SetQueueData(); + tcp_server2_.SetQueueData(); + } + tcp_server1_.Start(); + tcp_server2_.Start(); + ServerBuilder builder; + if (GetParam().server_has_port) { + int port = grpc_pick_unused_port_or_die(); + first_picked_port_ = port; + server_address_ << "localhost:" << port; + auto creds = GetCredentialsProvider()->GetServerCredentials( + GetParam().credentials_type); + builder.AddListeningPort(server_address_.str(), creds); + gpr_log(GPR_INFO, "gRPC server listening on %s", + server_address_.str().c_str()); + } + auto server_creds = GetCredentialsProvider()->GetServerCredentials( + GetParam().credentials_type); + auto acceptor1 = builder.experimental().AddExternalConnectionAcceptor( + ServerBuilder::experimental_type::ExternalConnectionType::FROM_FD, + server_creds); + tcp_server1_.SetAcceptor(std::move(acceptor1)); + auto acceptor2 = builder.experimental().AddExternalConnectionAcceptor( + ServerBuilder::experimental_type::ExternalConnectionType::FROM_FD, + server_creds); + tcp_server2_.SetAcceptor(std::move(acceptor2)); + builder.RegisterService(&service_); + server_ = builder.BuildAndStart(); + is_server_started_ = true; + + tcp_server1_.Run(); + tcp_server2_.Run(); + } + + void TearDown() override { + tcp_server1_.Shutdown(); + tcp_server2_.Shutdown(); + if (is_server_started_) { + server_->Shutdown(); + } + if (first_picked_port_ > 0) { + grpc_recycle_unused_port(first_picked_port_); + } + } + + void ResetStubs() { + EXPECT_TRUE(is_server_started_); + ChannelArguments args; + args.SetInt(GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL, 1); + auto channel_creds = GetCredentialsProvider()->GetChannelCredentials( + GetParam().credentials_type, &args); + channel_handoff1_ = + CreateCustomChannel(tcp_server1_.address(), channel_creds, args); + stub_handoff1_ = EchoTestService::NewStub(channel_handoff1_); + channel_handoff2_ = + CreateCustomChannel(tcp_server2_.address(), channel_creds, args); + stub_handoff2_ = EchoTestService::NewStub(channel_handoff2_); + if (GetParam().server_has_port) { + ChannelArguments direct_args; + direct_args.SetInt(GRPC_ARG_USE_LOCAL_SUBCHANNEL_POOL, 1); + auto direct_creds = GetCredentialsProvider()->GetChannelCredentials( + GetParam().credentials_type, &direct_args); + channel_direct_ = + CreateCustomChannel(server_address_.str(), direct_creds, direct_args); + stub_direct_ = EchoTestService::NewStub(channel_direct_); + } + } + + bool is_server_started_; + // channel/stub to the test tcp server, the connection will be handed to the + // grpc server. + std::shared_ptr<Channel> channel_handoff1_; + std::unique_ptr<EchoTestService::Stub> stub_handoff1_; + std::shared_ptr<Channel> channel_handoff2_; + std::unique_ptr<EchoTestService::Stub> stub_handoff2_; + // channel/stub to talk to the grpc server directly, if applicable. + std::shared_ptr<Channel> channel_direct_; + std::unique_ptr<EchoTestService::Stub> stub_direct_; + std::unique_ptr<Server> server_; + std::ostringstream server_address_; + TestServiceImpl service_; + TestTcpServer tcp_server1_; + TestTcpServer tcp_server2_; + int first_picked_port_; +}; + +static void SendRpc(EchoTestService::Stub* stub, int num_rpcs) { + EchoRequest request; + EchoResponse response; + request.set_message("Hello hello hello hello"); + + for (int i = 0; i < num_rpcs; ++i) { + ClientContext context; + Status s = stub->Echo(&context, request, &response); + EXPECT_EQ(response.message(), request.message()); + EXPECT_TRUE(s.ok()); + } +} + +std::vector<TestScenario> CreateTestScenarios() { + std::vector<TestScenario> scenarios; std::vector<TString> credentials_types; - -#if TARGET_OS_IPHONE - // Workaround Apple CFStream bug - gpr_setenv("grpc_cfstream", "0"); -#endif - - credentials_types = GetCredentialsProvider()->GetSecureCredentialsTypeList(); - // Only allow insecure credentials type when it is registered with the - // provider. User may create providers that do not have insecure. - if (GetCredentialsProvider()->GetChannelCredentials(kInsecureCredentialsType, - nullptr) != nullptr) { - credentials_types.push_back(kInsecureCredentialsType); - } - - GPR_ASSERT(!credentials_types.empty()); - for (const auto& cred : credentials_types) { - for (auto server_has_port : {true, false}) { - for (auto queue_pending_data : {true, false}) { - scenarios.emplace_back(server_has_port, queue_pending_data, cred); - } - } - } - return scenarios; -} - -TEST_P(PortSharingEnd2endTest, HandoffAndDirectCalls) { - ResetStubs(); - SendRpc(stub_handoff1_.get(), 5); - if (GetParam().server_has_port) { - SendRpc(stub_direct_.get(), 5); - } -} - -TEST_P(PortSharingEnd2endTest, MultipleHandoff) { - for (int i = 0; i < 3; i++) { - ResetStubs(); - SendRpc(stub_handoff2_.get(), 1); - } -} - -TEST_P(PortSharingEnd2endTest, TwoHandoffPorts) { - for (int i = 0; i < 3; i++) { - ResetStubs(); - SendRpc(stub_handoff1_.get(), 5); - SendRpc(stub_handoff2_.get(), 5); - } -} - -INSTANTIATE_TEST_SUITE_P(PortSharingEnd2end, PortSharingEnd2endTest, - ::testing::ValuesIn(CreateTestScenarios())); - -} // namespace -} // namespace testing -} // namespace grpc - -#endif // GRPC_POSIX_SOCKET_TCP_SERVER - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} + +#if TARGET_OS_IPHONE + // Workaround Apple CFStream bug + gpr_setenv("grpc_cfstream", "0"); +#endif + + credentials_types = GetCredentialsProvider()->GetSecureCredentialsTypeList(); + // Only allow insecure credentials type when it is registered with the + // provider. User may create providers that do not have insecure. + if (GetCredentialsProvider()->GetChannelCredentials(kInsecureCredentialsType, + nullptr) != nullptr) { + credentials_types.push_back(kInsecureCredentialsType); + } + + GPR_ASSERT(!credentials_types.empty()); + for (const auto& cred : credentials_types) { + for (auto server_has_port : {true, false}) { + for (auto queue_pending_data : {true, false}) { + scenarios.emplace_back(server_has_port, queue_pending_data, cred); + } + } + } + return scenarios; +} + +TEST_P(PortSharingEnd2endTest, HandoffAndDirectCalls) { + ResetStubs(); + SendRpc(stub_handoff1_.get(), 5); + if (GetParam().server_has_port) { + SendRpc(stub_direct_.get(), 5); + } +} + +TEST_P(PortSharingEnd2endTest, MultipleHandoff) { + for (int i = 0; i < 3; i++) { + ResetStubs(); + SendRpc(stub_handoff2_.get(), 1); + } +} + +TEST_P(PortSharingEnd2endTest, TwoHandoffPorts) { + for (int i = 0; i < 3; i++) { + ResetStubs(); + SendRpc(stub_handoff1_.get(), 5); + SendRpc(stub_handoff2_.get(), 5); + } +} + +INSTANTIATE_TEST_SUITE_P(PortSharingEnd2end, PortSharingEnd2endTest, + ::testing::ValuesIn(CreateTestScenarios())); + +} // namespace +} // namespace testing +} // namespace grpc + +#endif // GRPC_POSIX_SOCKET_TCP_SERVER + +int main(int argc, char** argv) { + grpc::testing::TestEnvironment env(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/contrib/libs/grpc/test/cpp/end2end/service_config_end2end_test.cc b/contrib/libs/grpc/test/cpp/end2end/service_config_end2end_test.cc index cee33343c11..0c6c5277dd6 100644 --- a/contrib/libs/grpc/test/cpp/end2end/service_config_end2end_test.cc +++ b/contrib/libs/grpc/test/cpp/end2end/service_config_end2end_test.cc @@ -1,613 +1,613 @@ -/* - * - * Copyright 2016 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 <algorithm> -#include <memory> -#include <mutex> -#include <random> -#include <set> +/* + * + * Copyright 2016 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 <algorithm> +#include <memory> +#include <mutex> +#include <random> +#include <set> #include <util/generic/string.h> -#include <thread> - +#include <thread> + #include "y_absl/strings/str_cat.h" -#include <grpc/grpc.h> -#include <grpc/support/alloc.h> -#include <grpc/support/atm.h> -#include <grpc/support/log.h> -#include <grpc/support/time.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/health_check_service_interface.h> -#include <grpcpp/impl/codegen/sync.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/support/validate_service_config.h> - -#include "src/core/ext/filters/client_channel/backup_poller.h" -#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" -#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" -#include "src/core/ext/filters/client_channel/server_address.h" -#include "src/core/lib/backoff/backoff.h" -#include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gprpp/debug_location.h" -#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/atm.h> +#include <grpc/support/log.h> +#include <grpc/support/time.h> +#include <grpcpp/channel.h> +#include <grpcpp/client_context.h> +#include <grpcpp/create_channel.h> +#include <grpcpp/health_check_service_interface.h> +#include <grpcpp/impl/codegen/sync.h> +#include <grpcpp/server.h> +#include <grpcpp/server_builder.h> +#include <grpcpp/support/validate_service_config.h> + +#include "src/core/ext/filters/client_channel/backup_poller.h" +#include "src/core/ext/filters/client_channel/global_subchannel_pool.h" +#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" +#include "src/core/ext/filters/client_channel/server_address.h" +#include "src/core/lib/backoff/backoff.h" +#include "src/core/lib/channel/channel_args.h" +#include "src/core/lib/gprpp/debug_location.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" #include "src/core/lib/iomgr/parse_address.h" -#include "src/core/lib/iomgr/tcp_client.h" -#include "src/core/lib/security/credentials/fake/fake_credentials.h" -#include "src/cpp/client/secure_credentials.h" -#include "src/cpp/server/secure_server_credentials.h" - -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/end2end/test_service_impl.h" - -#include <gmock/gmock.h> -#include <gtest/gtest.h> - -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; -using std::chrono::system_clock; - -namespace grpc { -namespace testing { -namespace { - -// Subclass of TestServiceImpl that increments a request counter for -// every call to the Echo RPC. -class MyTestServiceImpl : public TestServiceImpl { - public: - MyTestServiceImpl() : request_count_(0) {} - - Status Echo(ServerContext* context, const EchoRequest* request, - EchoResponse* response) override { - { - grpc::internal::MutexLock lock(&mu_); - ++request_count_; - } - AddClient(context->peer()); - return TestServiceImpl::Echo(context, request, response); - } - - int request_count() { - grpc::internal::MutexLock lock(&mu_); - return request_count_; - } - - void ResetCounters() { - grpc::internal::MutexLock lock(&mu_); - request_count_ = 0; - } - +#include "src/core/lib/iomgr/tcp_client.h" +#include "src/core/lib/security/credentials/fake/fake_credentials.h" +#include "src/cpp/client/secure_credentials.h" +#include "src/cpp/server/secure_server_credentials.h" + +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/end2end/test_service_impl.h" + +#include <gmock/gmock.h> +#include <gtest/gtest.h> + +using grpc::testing::EchoRequest; +using grpc::testing::EchoResponse; +using std::chrono::system_clock; + +namespace grpc { +namespace testing { +namespace { + +// Subclass of TestServiceImpl that increments a request counter for +// every call to the Echo RPC. +class MyTestServiceImpl : public TestServiceImpl { + public: + MyTestServiceImpl() : request_count_(0) {} + + Status Echo(ServerContext* context, const EchoRequest* request, + EchoResponse* response) override { + { + grpc::internal::MutexLock lock(&mu_); + ++request_count_; + } + AddClient(context->peer()); + return TestServiceImpl::Echo(context, request, response); + } + + int request_count() { + grpc::internal::MutexLock lock(&mu_); + return request_count_; + } + + void ResetCounters() { + grpc::internal::MutexLock lock(&mu_); + request_count_ = 0; + } + std::set<TString> clients() { - grpc::internal::MutexLock lock(&clients_mu_); - return clients_; - } - - private: + grpc::internal::MutexLock lock(&clients_mu_); + return clients_; + } + + private: void AddClient(const TString& client) { - grpc::internal::MutexLock lock(&clients_mu_); - clients_.insert(client); - } - - grpc::internal::Mutex mu_; - int request_count_; - grpc::internal::Mutex clients_mu_; + grpc::internal::MutexLock lock(&clients_mu_); + clients_.insert(client); + } + + grpc::internal::Mutex mu_; + int request_count_; + grpc::internal::Mutex clients_mu_; std::set<TString> clients_; -}; - -class ServiceConfigEnd2endTest : public ::testing::Test { - protected: - ServiceConfigEnd2endTest() - : server_host_("localhost"), - kRequestMessage_("Live long and prosper."), - creds_(new SecureChannelCredentials( - grpc_fake_transport_security_credentials_create())) {} - - static void SetUpTestCase() { - // Make the backup poller poll very frequently in order to pick up - // updates from all the subchannels's FDs. - GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); - } - - void SetUp() override { - grpc_init(); - response_generator_ = - grpc_core::MakeRefCounted<grpc_core::FakeResolverResponseGenerator>(); - } - - void TearDown() override { - for (size_t i = 0; i < servers_.size(); ++i) { - servers_[i]->Shutdown(); - } - // Explicitly destroy all the members so that we can make sure grpc_shutdown - // has finished by the end of this function, and thus all the registered - // LB policy factories are removed. - stub_.reset(); - servers_.clear(); - creds_.reset(); - grpc_shutdown_blocking(); - } - - void CreateServers(size_t num_servers, - std::vector<int> ports = std::vector<int>()) { - servers_.clear(); - for (size_t i = 0; i < num_servers; ++i) { - int port = 0; - if (ports.size() == num_servers) port = ports[i]; - servers_.emplace_back(new ServerData(port)); - } - } - - void StartServer(size_t index) { servers_[index]->Start(server_host_); } - - void StartServers(size_t num_servers, - std::vector<int> ports = std::vector<int>()) { - CreateServers(num_servers, std::move(ports)); - for (size_t i = 0; i < num_servers; ++i) { - StartServer(i); - } - } - - grpc_core::Resolver::Result BuildFakeResults(const std::vector<int>& ports) { - grpc_core::Resolver::Result result; - for (const int& port : ports) { +}; + +class ServiceConfigEnd2endTest : public ::testing::Test { + protected: + ServiceConfigEnd2endTest() + : server_host_("localhost"), + kRequestMessage_("Live long and prosper."), + creds_(new SecureChannelCredentials( + grpc_fake_transport_security_credentials_create())) {} + + static void SetUpTestCase() { + // Make the backup poller poll very frequently in order to pick up + // updates from all the subchannels's FDs. + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); + } + + void SetUp() override { + grpc_init(); + response_generator_ = + grpc_core::MakeRefCounted<grpc_core::FakeResolverResponseGenerator>(); + } + + void TearDown() override { + for (size_t i = 0; i < servers_.size(); ++i) { + servers_[i]->Shutdown(); + } + // Explicitly destroy all the members so that we can make sure grpc_shutdown + // has finished by the end of this function, and thus all the registered + // LB policy factories are removed. + stub_.reset(); + servers_.clear(); + creds_.reset(); + grpc_shutdown_blocking(); + } + + void CreateServers(size_t num_servers, + std::vector<int> ports = std::vector<int>()) { + servers_.clear(); + for (size_t i = 0; i < num_servers; ++i) { + int port = 0; + if (ports.size() == num_servers) port = ports[i]; + servers_.emplace_back(new ServerData(port)); + } + } + + void StartServer(size_t index) { servers_[index]->Start(server_host_); } + + void StartServers(size_t num_servers, + std::vector<int> ports = std::vector<int>()) { + CreateServers(num_servers, std::move(ports)); + for (size_t i = 0; i < num_servers; ++i) { + StartServer(i); + } + } + + grpc_core::Resolver::Result BuildFakeResults(const std::vector<int>& ports) { + grpc_core::Resolver::Result result; + for (const int& port : ports) { TString lb_uri_str = y_absl::StrCat("ipv4:127.0.0.1:", port); grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str.c_str(), true); - GPR_ASSERT(lb_uri != nullptr); - grpc_resolved_address address; - GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); - result.addresses.emplace_back(address.addr, address.len, - nullptr /* args */); - grpc_uri_destroy(lb_uri); - } - return result; - } - - void SetNextResolutionNoServiceConfig(const std::vector<int>& ports) { - grpc_core::ExecCtx exec_ctx; - grpc_core::Resolver::Result result = BuildFakeResults(ports); - response_generator_->SetResponse(result); - } - - void SetNextResolutionValidServiceConfig(const std::vector<int>& ports) { - grpc_core::ExecCtx exec_ctx; - grpc_core::Resolver::Result result = BuildFakeResults(ports); + GPR_ASSERT(lb_uri != nullptr); + grpc_resolved_address address; + GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); + result.addresses.emplace_back(address.addr, address.len, + nullptr /* args */); + grpc_uri_destroy(lb_uri); + } + return result; + } + + void SetNextResolutionNoServiceConfig(const std::vector<int>& ports) { + grpc_core::ExecCtx exec_ctx; + grpc_core::Resolver::Result result = BuildFakeResults(ports); + response_generator_->SetResponse(result); + } + + void SetNextResolutionValidServiceConfig(const std::vector<int>& ports) { + grpc_core::ExecCtx exec_ctx; + grpc_core::Resolver::Result result = BuildFakeResults(ports); result.service_config = grpc_core::ServiceConfig::Create( nullptr, "{}", &result.service_config_error); - response_generator_->SetResponse(result); - } - - void SetNextResolutionInvalidServiceConfig(const std::vector<int>& ports) { - grpc_core::ExecCtx exec_ctx; - grpc_core::Resolver::Result result = BuildFakeResults(ports); + response_generator_->SetResponse(result); + } + + void SetNextResolutionInvalidServiceConfig(const std::vector<int>& ports) { + grpc_core::ExecCtx exec_ctx; + grpc_core::Resolver::Result result = BuildFakeResults(ports); result.service_config = grpc_core::ServiceConfig::Create( nullptr, "{", &result.service_config_error); - response_generator_->SetResponse(result); - } - - void SetNextResolutionWithServiceConfig(const std::vector<int>& ports, - const char* svc_cfg) { - grpc_core::ExecCtx exec_ctx; - grpc_core::Resolver::Result result = BuildFakeResults(ports); + response_generator_->SetResponse(result); + } + + void SetNextResolutionWithServiceConfig(const std::vector<int>& ports, + const char* svc_cfg) { + grpc_core::ExecCtx exec_ctx; + grpc_core::Resolver::Result result = BuildFakeResults(ports); result.service_config = grpc_core::ServiceConfig::Create( nullptr, svc_cfg, &result.service_config_error); - response_generator_->SetResponse(result); - } - - std::vector<int> GetServersPorts(size_t start_index = 0) { - std::vector<int> ports; - for (size_t i = start_index; i < servers_.size(); ++i) { - ports.push_back(servers_[i]->port_); - } - return ports; - } - - std::unique_ptr<grpc::testing::EchoTestService::Stub> BuildStub( - const std::shared_ptr<Channel>& channel) { - return grpc::testing::EchoTestService::NewStub(channel); - } - - std::shared_ptr<Channel> BuildChannel() { - ChannelArguments args; - args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, - response_generator_.get()); - return ::grpc::CreateCustomChannel("fake:///", creds_, args); - } - - std::shared_ptr<Channel> BuildChannelWithDefaultServiceConfig() { - ChannelArguments args; - EXPECT_THAT(grpc::experimental::ValidateServiceConfigJSON( - ValidDefaultServiceConfig()), - ::testing::StrEq("")); - args.SetServiceConfigJSON(ValidDefaultServiceConfig()); - args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, - response_generator_.get()); - return ::grpc::CreateCustomChannel("fake:///", creds_, args); - } - - std::shared_ptr<Channel> BuildChannelWithInvalidDefaultServiceConfig() { - ChannelArguments args; + response_generator_->SetResponse(result); + } + + std::vector<int> GetServersPorts(size_t start_index = 0) { + std::vector<int> ports; + for (size_t i = start_index; i < servers_.size(); ++i) { + ports.push_back(servers_[i]->port_); + } + return ports; + } + + std::unique_ptr<grpc::testing::EchoTestService::Stub> BuildStub( + const std::shared_ptr<Channel>& channel) { + return grpc::testing::EchoTestService::NewStub(channel); + } + + std::shared_ptr<Channel> BuildChannel() { + ChannelArguments args; + args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, + response_generator_.get()); + return ::grpc::CreateCustomChannel("fake:///", creds_, args); + } + + std::shared_ptr<Channel> BuildChannelWithDefaultServiceConfig() { + ChannelArguments args; + EXPECT_THAT(grpc::experimental::ValidateServiceConfigJSON( + ValidDefaultServiceConfig()), + ::testing::StrEq("")); + args.SetServiceConfigJSON(ValidDefaultServiceConfig()); + args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, + response_generator_.get()); + return ::grpc::CreateCustomChannel("fake:///", creds_, args); + } + + std::shared_ptr<Channel> BuildChannelWithInvalidDefaultServiceConfig() { + ChannelArguments args; EXPECT_THAT(grpc::experimental::ValidateServiceConfigJSON( InvalidDefaultServiceConfig()), ::testing::HasSubstr("JSON parse error")); - args.SetServiceConfigJSON(InvalidDefaultServiceConfig()); - args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, - response_generator_.get()); - return ::grpc::CreateCustomChannel("fake:///", creds_, args); - } - - bool SendRpc( - const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, - EchoResponse* response = nullptr, int timeout_ms = 1000, - Status* result = nullptr, bool wait_for_ready = false) { - const bool local_response = (response == nullptr); - if (local_response) response = new EchoResponse; - EchoRequest request; - request.set_message(kRequestMessage_); - ClientContext context; - context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms)); - if (wait_for_ready) context.set_wait_for_ready(true); - Status status = stub->Echo(&context, request, response); - if (result != nullptr) *result = status; - if (local_response) delete response; - return status.ok(); - } - - void CheckRpcSendOk( - const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, - const grpc_core::DebugLocation& location, bool wait_for_ready = false) { - EchoResponse response; - Status status; - const bool success = - SendRpc(stub, &response, 2000, &status, wait_for_ready); - ASSERT_TRUE(success) << "From " << location.file() << ":" << location.line() - << "\n" - << "Error: " << status.error_message() << " " - << status.error_details(); - ASSERT_EQ(response.message(), kRequestMessage_) - << "From " << location.file() << ":" << location.line(); - if (!success) abort(); - } - - void CheckRpcSendFailure( - const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub) { - const bool success = SendRpc(stub); - EXPECT_FALSE(success); - } - - struct ServerData { - 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(); - } - + args.SetServiceConfigJSON(InvalidDefaultServiceConfig()); + args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, + response_generator_.get()); + return ::grpc::CreateCustomChannel("fake:///", creds_, args); + } + + bool SendRpc( + const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, + EchoResponse* response = nullptr, int timeout_ms = 1000, + Status* result = nullptr, bool wait_for_ready = false) { + const bool local_response = (response == nullptr); + if (local_response) response = new EchoResponse; + EchoRequest request; + request.set_message(kRequestMessage_); + ClientContext context; + context.set_deadline(grpc_timeout_milliseconds_to_deadline(timeout_ms)); + if (wait_for_ready) context.set_wait_for_ready(true); + Status status = stub->Echo(&context, request, response); + if (result != nullptr) *result = status; + if (local_response) delete response; + return status.ok(); + } + + void CheckRpcSendOk( + const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, + const grpc_core::DebugLocation& location, bool wait_for_ready = false) { + EchoResponse response; + Status status; + const bool success = + SendRpc(stub, &response, 2000, &status, wait_for_ready); + ASSERT_TRUE(success) << "From " << location.file() << ":" << location.line() + << "\n" + << "Error: " << status.error_message() << " " + << status.error_details(); + ASSERT_EQ(response.message(), kRequestMessage_) + << "From " << location.file() << ":" << location.line(); + if (!success) abort(); + } + + void CheckRpcSendFailure( + const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub) { + const bool success = SendRpc(stub); + EXPECT_FALSE(success); + } + + struct ServerData { + 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(); + } + void Start(const TString& server_host) { - gpr_log(GPR_INFO, "starting server on port %d", port_); - started_ = true; - grpc::internal::Mutex mu; - grpc::internal::MutexLock lock(&mu); - grpc::internal::CondVar cond; - thread_.reset(new std::thread( - std::bind(&ServerData::Serve, this, server_host, &mu, &cond))); - cond.WaitUntil(&mu, [this] { return server_ready_; }); - server_ready_ = false; - gpr_log(GPR_INFO, "server startup complete"); - } - + gpr_log(GPR_INFO, "starting server on port %d", port_); + started_ = true; + grpc::internal::Mutex mu; + grpc::internal::MutexLock lock(&mu); + grpc::internal::CondVar cond; + thread_.reset(new std::thread( + std::bind(&ServerData::Serve, this, server_host, &mu, &cond))); + cond.WaitUntil(&mu, [this] { return server_ready_; }); + server_ready_ = false; + gpr_log(GPR_INFO, "server startup complete"); + } + void Serve(const TString& server_host, grpc::internal::Mutex* mu, - grpc::internal::CondVar* cond) { - std::ostringstream server_address; - server_address << server_host << ":" << port_; - ServerBuilder builder; - std::shared_ptr<ServerCredentials> creds(new SecureServerCredentials( - grpc_fake_transport_security_server_credentials_create())); - builder.AddListeningPort(server_address.str(), std::move(creds)); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - grpc::internal::MutexLock lock(mu); - server_ready_ = true; - cond->Signal(); - } - - void Shutdown() { - if (!started_) return; - server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); - thread_->join(); - started_ = false; - } - + grpc::internal::CondVar* cond) { + std::ostringstream server_address; + server_address << server_host << ":" << port_; + ServerBuilder builder; + std::shared_ptr<ServerCredentials> creds(new SecureServerCredentials( + grpc_fake_transport_security_server_credentials_create())); + builder.AddListeningPort(server_address.str(), std::move(creds)); + builder.RegisterService(&service_); + server_ = builder.BuildAndStart(); + grpc::internal::MutexLock lock(mu); + server_ready_ = true; + cond->Signal(); + } + + void Shutdown() { + if (!started_) return; + server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); + thread_->join(); + started_ = false; + } + void SetServingStatus(const TString& service, bool serving) { - server_->GetHealthCheckService()->SetServingStatus(service, serving); - } - }; - - void ResetCounters() { - for (const auto& server : servers_) server->service_.ResetCounters(); - } - - void WaitForServer( - const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, - size_t server_idx, const grpc_core::DebugLocation& location, - bool ignore_failure = false) { - do { - if (ignore_failure) { - SendRpc(stub); - } else { - CheckRpcSendOk(stub, location, true); - } - } while (servers_[server_idx]->service_.request_count() == 0); - ResetCounters(); - } - - bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { - const gpr_timespec deadline = - grpc_timeout_seconds_to_deadline(timeout_seconds); - grpc_connectivity_state state; - while ((state = channel->GetState(false /* try_to_connect */)) == - GRPC_CHANNEL_READY) { - if (!channel->WaitForStateChange(state, deadline)) return false; - } - return true; - } - - bool WaitForChannelReady(Channel* channel, int timeout_seconds = 5) { - const gpr_timespec deadline = - grpc_timeout_seconds_to_deadline(timeout_seconds); - grpc_connectivity_state state; - while ((state = channel->GetState(true /* try_to_connect */)) != - GRPC_CHANNEL_READY) { - if (!channel->WaitForStateChange(state, deadline)) return false; - } - return true; - } - - bool SeenAllServers() { - for (const auto& server : servers_) { - if (server->service_.request_count() == 0) return false; - } - return true; - } - - // Updates \a connection_order by appending to it the index of the newly - // connected server. Must be called after every single RPC. - void UpdateConnectionOrder( - const std::vector<std::unique_ptr<ServerData>>& servers, - std::vector<int>* connection_order) { - for (size_t i = 0; i < servers.size(); ++i) { - if (servers[i]->service_.request_count() == 1) { - // Was the server index known? If not, update connection_order. - const auto it = - std::find(connection_order->begin(), connection_order->end(), i); - if (it == connection_order->end()) { - connection_order->push_back(i); - return; - } - } - } - } - - const char* ValidServiceConfigV1() { return "{\"version\": \"1\"}"; } - - const char* ValidServiceConfigV2() { return "{\"version\": \"2\"}"; } - - const char* ValidDefaultServiceConfig() { - return "{\"version\": \"valid_default\"}"; - } - - const char* InvalidDefaultServiceConfig() { - return "{\"version\": \"invalid_default\""; - } - + server_->GetHealthCheckService()->SetServingStatus(service, serving); + } + }; + + void ResetCounters() { + for (const auto& server : servers_) server->service_.ResetCounters(); + } + + void WaitForServer( + const std::unique_ptr<grpc::testing::EchoTestService::Stub>& stub, + size_t server_idx, const grpc_core::DebugLocation& location, + bool ignore_failure = false) { + do { + if (ignore_failure) { + SendRpc(stub); + } else { + CheckRpcSendOk(stub, location, true); + } + } while (servers_[server_idx]->service_.request_count() == 0); + ResetCounters(); + } + + bool WaitForChannelNotReady(Channel* channel, int timeout_seconds = 5) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(false /* try_to_connect */)) == + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + + bool WaitForChannelReady(Channel* channel, int timeout_seconds = 5) { + const gpr_timespec deadline = + grpc_timeout_seconds_to_deadline(timeout_seconds); + grpc_connectivity_state state; + while ((state = channel->GetState(true /* try_to_connect */)) != + GRPC_CHANNEL_READY) { + if (!channel->WaitForStateChange(state, deadline)) return false; + } + return true; + } + + bool SeenAllServers() { + for (const auto& server : servers_) { + if (server->service_.request_count() == 0) return false; + } + return true; + } + + // Updates \a connection_order by appending to it the index of the newly + // connected server. Must be called after every single RPC. + void UpdateConnectionOrder( + const std::vector<std::unique_ptr<ServerData>>& servers, + std::vector<int>* connection_order) { + for (size_t i = 0; i < servers.size(); ++i) { + if (servers[i]->service_.request_count() == 1) { + // Was the server index known? If not, update connection_order. + const auto it = + std::find(connection_order->begin(), connection_order->end(), i); + if (it == connection_order->end()) { + connection_order->push_back(i); + return; + } + } + } + } + + const char* ValidServiceConfigV1() { return "{\"version\": \"1\"}"; } + + const char* ValidServiceConfigV2() { return "{\"version\": \"2\"}"; } + + const char* ValidDefaultServiceConfig() { + return "{\"version\": \"valid_default\"}"; + } + + const char* InvalidDefaultServiceConfig() { + return "{\"version\": \"invalid_default\""; + } + const TString server_host_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::vector<std::unique_ptr<ServerData>> servers_; - grpc_core::RefCountedPtr<grpc_core::FakeResolverResponseGenerator> - response_generator_; + std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; + std::vector<std::unique_ptr<ServerData>> servers_; + grpc_core::RefCountedPtr<grpc_core::FakeResolverResponseGenerator> + response_generator_; const TString kRequestMessage_; - std::shared_ptr<ChannelCredentials> creds_; -}; - -TEST_F(ServiceConfigEnd2endTest, NoServiceConfigTest) { - StartServers(1); - auto channel = BuildChannel(); - auto stub = BuildStub(channel); - SetNextResolutionNoServiceConfig(GetServersPorts()); - CheckRpcSendOk(stub, DEBUG_LOCATION); + std::shared_ptr<ChannelCredentials> creds_; +}; + +TEST_F(ServiceConfigEnd2endTest, NoServiceConfigTest) { + StartServers(1); + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + SetNextResolutionNoServiceConfig(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); EXPECT_STREQ("{}", channel->GetServiceConfigJSON().c_str()); -} - -TEST_F(ServiceConfigEnd2endTest, NoServiceConfigWithDefaultConfigTest) { - StartServers(1); - auto channel = BuildChannelWithDefaultServiceConfig(); - auto stub = BuildStub(channel); - SetNextResolutionNoServiceConfig(GetServersPorts()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_STREQ(ValidDefaultServiceConfig(), - channel->GetServiceConfigJSON().c_str()); -} - -TEST_F(ServiceConfigEnd2endTest, InvalidServiceConfigTest) { - StartServers(1); - auto channel = BuildChannel(); - auto stub = BuildStub(channel); - SetNextResolutionInvalidServiceConfig(GetServersPorts()); - CheckRpcSendFailure(stub); -} - -TEST_F(ServiceConfigEnd2endTest, ValidServiceConfigUpdatesTest) { - StartServers(1); - auto channel = BuildChannel(); - auto stub = BuildStub(channel); - SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV1()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); - SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV2()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_STREQ(ValidServiceConfigV2(), channel->GetServiceConfigJSON().c_str()); -} - -TEST_F(ServiceConfigEnd2endTest, - NoServiceConfigUpdateAfterValidServiceConfigTest) { - StartServers(1); - auto channel = BuildChannel(); - auto stub = BuildStub(channel); - SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV1()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); - SetNextResolutionNoServiceConfig(GetServersPorts()); - CheckRpcSendOk(stub, DEBUG_LOCATION); +} + +TEST_F(ServiceConfigEnd2endTest, NoServiceConfigWithDefaultConfigTest) { + StartServers(1); + auto channel = BuildChannelWithDefaultServiceConfig(); + auto stub = BuildStub(channel); + SetNextResolutionNoServiceConfig(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ(ValidDefaultServiceConfig(), + channel->GetServiceConfigJSON().c_str()); +} + +TEST_F(ServiceConfigEnd2endTest, InvalidServiceConfigTest) { + StartServers(1); + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + SetNextResolutionInvalidServiceConfig(GetServersPorts()); + CheckRpcSendFailure(stub); +} + +TEST_F(ServiceConfigEnd2endTest, ValidServiceConfigUpdatesTest) { + StartServers(1); + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV1()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); + SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV2()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ(ValidServiceConfigV2(), channel->GetServiceConfigJSON().c_str()); +} + +TEST_F(ServiceConfigEnd2endTest, + NoServiceConfigUpdateAfterValidServiceConfigTest) { + StartServers(1); + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV1()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); + SetNextResolutionNoServiceConfig(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); EXPECT_STREQ("{}", channel->GetServiceConfigJSON().c_str()); -} - -TEST_F(ServiceConfigEnd2endTest, - NoServiceConfigUpdateAfterValidServiceConfigWithDefaultConfigTest) { - StartServers(1); - auto channel = BuildChannelWithDefaultServiceConfig(); - auto stub = BuildStub(channel); - SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV1()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); - SetNextResolutionNoServiceConfig(GetServersPorts()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_STREQ(ValidDefaultServiceConfig(), - channel->GetServiceConfigJSON().c_str()); -} - -TEST_F(ServiceConfigEnd2endTest, - InvalidServiceConfigUpdateAfterValidServiceConfigTest) { - StartServers(1); - auto channel = BuildChannel(); - auto stub = BuildStub(channel); - SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV1()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); - SetNextResolutionInvalidServiceConfig(GetServersPorts()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); -} - -TEST_F(ServiceConfigEnd2endTest, - InvalidServiceConfigUpdateAfterValidServiceConfigWithDefaultConfigTest) { - StartServers(1); - auto channel = BuildChannelWithDefaultServiceConfig(); - auto stub = BuildStub(channel); - SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV1()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); - SetNextResolutionInvalidServiceConfig(GetServersPorts()); - CheckRpcSendOk(stub, DEBUG_LOCATION); - EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); -} - -TEST_F(ServiceConfigEnd2endTest, - ValidServiceConfigAfterInvalidServiceConfigTest) { - StartServers(1); - auto channel = BuildChannel(); - auto stub = BuildStub(channel); - SetNextResolutionInvalidServiceConfig(GetServersPorts()); - CheckRpcSendFailure(stub); - SetNextResolutionValidServiceConfig(GetServersPorts()); - CheckRpcSendOk(stub, DEBUG_LOCATION); -} - -TEST_F(ServiceConfigEnd2endTest, NoServiceConfigAfterInvalidServiceConfigTest) { - StartServers(1); - auto channel = BuildChannel(); - auto stub = BuildStub(channel); - SetNextResolutionInvalidServiceConfig(GetServersPorts()); - CheckRpcSendFailure(stub); - SetNextResolutionNoServiceConfig(GetServersPorts()); - CheckRpcSendOk(stub, DEBUG_LOCATION); +} + +TEST_F(ServiceConfigEnd2endTest, + NoServiceConfigUpdateAfterValidServiceConfigWithDefaultConfigTest) { + StartServers(1); + auto channel = BuildChannelWithDefaultServiceConfig(); + auto stub = BuildStub(channel); + SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV1()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); + SetNextResolutionNoServiceConfig(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ(ValidDefaultServiceConfig(), + channel->GetServiceConfigJSON().c_str()); +} + +TEST_F(ServiceConfigEnd2endTest, + InvalidServiceConfigUpdateAfterValidServiceConfigTest) { + StartServers(1); + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV1()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); + SetNextResolutionInvalidServiceConfig(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); +} + +TEST_F(ServiceConfigEnd2endTest, + InvalidServiceConfigUpdateAfterValidServiceConfigWithDefaultConfigTest) { + StartServers(1); + auto channel = BuildChannelWithDefaultServiceConfig(); + auto stub = BuildStub(channel); + SetNextResolutionWithServiceConfig(GetServersPorts(), ValidServiceConfigV1()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); + SetNextResolutionInvalidServiceConfig(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); + EXPECT_STREQ(ValidServiceConfigV1(), channel->GetServiceConfigJSON().c_str()); +} + +TEST_F(ServiceConfigEnd2endTest, + ValidServiceConfigAfterInvalidServiceConfigTest) { + StartServers(1); + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + SetNextResolutionInvalidServiceConfig(GetServersPorts()); + CheckRpcSendFailure(stub); + SetNextResolutionValidServiceConfig(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); +} + +TEST_F(ServiceConfigEnd2endTest, NoServiceConfigAfterInvalidServiceConfigTest) { + StartServers(1); + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + SetNextResolutionInvalidServiceConfig(GetServersPorts()); + CheckRpcSendFailure(stub); + SetNextResolutionNoServiceConfig(GetServersPorts()); + CheckRpcSendOk(stub, DEBUG_LOCATION); EXPECT_STREQ("{}", channel->GetServiceConfigJSON().c_str()); -} - -TEST_F(ServiceConfigEnd2endTest, - AnotherInvalidServiceConfigAfterInvalidServiceConfigTest) { - StartServers(1); - auto channel = BuildChannel(); - auto stub = BuildStub(channel); - SetNextResolutionInvalidServiceConfig(GetServersPorts()); - CheckRpcSendFailure(stub); - SetNextResolutionInvalidServiceConfig(GetServersPorts()); - CheckRpcSendFailure(stub); -} - -TEST_F(ServiceConfigEnd2endTest, InvalidDefaultServiceConfigTest) { - StartServers(1); - auto channel = BuildChannelWithInvalidDefaultServiceConfig(); - auto stub = BuildStub(channel); - // An invalid default service config results in a lame channel which fails all - // RPCs - CheckRpcSendFailure(stub); -} - -TEST_F(ServiceConfigEnd2endTest, - InvalidDefaultServiceConfigTestWithValidServiceConfig) { - StartServers(1); - auto channel = BuildChannelWithInvalidDefaultServiceConfig(); - auto stub = BuildStub(channel); - CheckRpcSendFailure(stub); - // An invalid default service config results in a lame channel which fails all - // RPCs - SetNextResolutionValidServiceConfig(GetServersPorts()); - CheckRpcSendFailure(stub); -} - -TEST_F(ServiceConfigEnd2endTest, - InvalidDefaultServiceConfigTestWithInvalidServiceConfig) { - StartServers(1); - auto channel = BuildChannelWithInvalidDefaultServiceConfig(); - auto stub = BuildStub(channel); - CheckRpcSendFailure(stub); - // An invalid default service config results in a lame channel which fails all - // RPCs - SetNextResolutionInvalidServiceConfig(GetServersPorts()); - CheckRpcSendFailure(stub); -} - -TEST_F(ServiceConfigEnd2endTest, - InvalidDefaultServiceConfigTestWithNoServiceConfig) { - StartServers(1); - auto channel = BuildChannelWithInvalidDefaultServiceConfig(); - auto stub = BuildStub(channel); - CheckRpcSendFailure(stub); - // An invalid default service config results in a lame channel which fails all - // RPCs - SetNextResolutionNoServiceConfig(GetServersPorts()); - CheckRpcSendFailure(stub); -} - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - ::testing::InitGoogleTest(&argc, argv); - grpc::testing::TestEnvironment env(argc, argv); - const auto result = RUN_ALL_TESTS(); - return result; -} +} + +TEST_F(ServiceConfigEnd2endTest, + AnotherInvalidServiceConfigAfterInvalidServiceConfigTest) { + StartServers(1); + auto channel = BuildChannel(); + auto stub = BuildStub(channel); + SetNextResolutionInvalidServiceConfig(GetServersPorts()); + CheckRpcSendFailure(stub); + SetNextResolutionInvalidServiceConfig(GetServersPorts()); + CheckRpcSendFailure(stub); +} + +TEST_F(ServiceConfigEnd2endTest, InvalidDefaultServiceConfigTest) { + StartServers(1); + auto channel = BuildChannelWithInvalidDefaultServiceConfig(); + auto stub = BuildStub(channel); + // An invalid default service config results in a lame channel which fails all + // RPCs + CheckRpcSendFailure(stub); +} + +TEST_F(ServiceConfigEnd2endTest, + InvalidDefaultServiceConfigTestWithValidServiceConfig) { + StartServers(1); + auto channel = BuildChannelWithInvalidDefaultServiceConfig(); + auto stub = BuildStub(channel); + CheckRpcSendFailure(stub); + // An invalid default service config results in a lame channel which fails all + // RPCs + SetNextResolutionValidServiceConfig(GetServersPorts()); + CheckRpcSendFailure(stub); +} + +TEST_F(ServiceConfigEnd2endTest, + InvalidDefaultServiceConfigTestWithInvalidServiceConfig) { + StartServers(1); + auto channel = BuildChannelWithInvalidDefaultServiceConfig(); + auto stub = BuildStub(channel); + CheckRpcSendFailure(stub); + // An invalid default service config results in a lame channel which fails all + // RPCs + SetNextResolutionInvalidServiceConfig(GetServersPorts()); + CheckRpcSendFailure(stub); +} + +TEST_F(ServiceConfigEnd2endTest, + InvalidDefaultServiceConfigTestWithNoServiceConfig) { + StartServers(1); + auto channel = BuildChannelWithInvalidDefaultServiceConfig(); + auto stub = BuildStub(channel); + CheckRpcSendFailure(stub); + // An invalid default service config results in a lame channel which fails all + // RPCs + SetNextResolutionNoServiceConfig(GetServersPorts()); + CheckRpcSendFailure(stub); +} + +} // namespace +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + ::testing::InitGoogleTest(&argc, argv); + grpc::testing::TestEnvironment env(argc, argv); + const auto result = RUN_ALL_TESTS(); + return result; +} diff --git a/contrib/libs/grpc/test/cpp/end2end/xds_end2end_test.cc b/contrib/libs/grpc/test/cpp/end2end/xds_end2end_test.cc index 603e6186bf0..eba94c0e0b4 100644 --- a/contrib/libs/grpc/test/cpp/end2end/xds_end2end_test.cc +++ b/contrib/libs/grpc/test/cpp/end2end/xds_end2end_test.cc @@ -1,76 +1,76 @@ -/* - * - * 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. - * - */ - +/* + * + * 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 <deque> -#include <memory> -#include <mutex> -#include <numeric> -#include <set> -#include <sstream> +#include <memory> +#include <mutex> +#include <numeric> +#include <set> +#include <sstream> #include <util/generic/string.h> -#include <thread> +#include <thread> #include <vector> - + #include <gmock/gmock.h> #include <gtest/gtest.h> #include "y_absl/strings/str_cat.h" #include "y_absl/types/optional.h" -#include <grpc/grpc.h> -#include <grpc/support/alloc.h> -#include <grpc/support/log.h> -#include <grpc/support/time.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> - -#include "src/core/ext/filters/client_channel/backup_poller.h" -#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" -#include "src/core/ext/filters/client_channel/server_address.h" +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpc/support/log.h> +#include <grpc/support/time.h> +#include <grpcpp/channel.h> +#include <grpcpp/client_context.h> +#include <grpcpp/create_channel.h> +#include <grpcpp/server.h> +#include <grpcpp/server_builder.h> + +#include "src/core/ext/filters/client_channel/backup_poller.h" +#include "src/core/ext/filters/client_channel/resolver/fake/fake_resolver.h" +#include "src/core/ext/filters/client_channel/server_address.h" #include "src/core/ext/xds/xds_api.h" #include "src/core/ext/xds/xds_channel_args.h" #include "src/core/ext/xds/xds_client.h" #include "src/core/lib/channel/channel_args.h" -#include "src/core/lib/gpr/env.h" -#include "src/core/lib/gpr/tmpfile.h" -#include "src/core/lib/gprpp/map.h" -#include "src/core/lib/gprpp/ref_counted_ptr.h" -#include "src/core/lib/gprpp/sync.h" +#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/tmpfile.h" +#include "src/core/lib/gprpp/map.h" +#include "src/core/lib/gprpp/ref_counted_ptr.h" +#include "src/core/lib/gprpp/sync.h" #include "src/core/lib/iomgr/parse_address.h" -#include "src/core/lib/iomgr/sockaddr.h" -#include "src/core/lib/security/credentials/fake/fake_credentials.h" -#include "src/cpp/client/secure_credentials.h" -#include "src/cpp/server/secure_server_credentials.h" - -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/end2end/test_service_impl.h" - -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "src/proto/grpc/testing/xds/ads_for_test.grpc.pb.h" +#include "src/core/lib/iomgr/sockaddr.h" +#include "src/core/lib/security/credentials/fake/fake_credentials.h" +#include "src/cpp/client/secure_credentials.h" +#include "src/cpp/server/secure_server_credentials.h" + +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/end2end/test_service_impl.h" + +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "src/proto/grpc/testing/xds/ads_for_test.grpc.pb.h" #include "src/proto/grpc/testing/xds/cds_for_test.grpc.pb.h" -#include "src/proto/grpc/testing/xds/eds_for_test.grpc.pb.h" +#include "src/proto/grpc/testing/xds/eds_for_test.grpc.pb.h" #include "src/proto/grpc/testing/xds/lds_rds_for_test.grpc.pb.h" -#include "src/proto/grpc/testing/xds/lrs_for_test.grpc.pb.h" - +#include "src/proto/grpc/testing/xds/lrs_for_test.grpc.pb.h" + #include "src/proto/grpc/testing/xds/v3/ads.grpc.pb.h" #include "src/proto/grpc/testing/xds/v3/cluster.grpc.pb.h" #include "src/proto/grpc/testing/xds/v3/discovery.grpc.pb.h" @@ -79,13 +79,13 @@ #include "src/proto/grpc/testing/xds/v3/listener.grpc.pb.h" #include "src/proto/grpc/testing/xds/v3/lrs.grpc.pb.h" #include "src/proto/grpc/testing/xds/v3/route.grpc.pb.h" - -namespace grpc { -namespace testing { -namespace { - -using std::chrono::system_clock; - + +namespace grpc { +namespace testing { +namespace { + +using std::chrono::system_clock; + using ::envoy::config::cluster::v3::CircuitBreakers; using ::envoy::config::cluster::v3::Cluster; using ::envoy::config::cluster::v3::RoutingPriority; @@ -96,7 +96,7 @@ using ::envoy::config::route::v3::RouteConfiguration; using ::envoy::extensions::filters::network::http_connection_manager::v3:: HttpConnectionManager; using ::envoy::type::v3::FractionalPercent; - + constexpr char kLdsTypeUrl[] = "type.googleapis.com/envoy.config.listener.v3.Listener"; constexpr char kRdsTypeUrl[] = @@ -111,22 +111,22 @@ constexpr char kRdsV2TypeUrl[] = "type.googleapis.com/envoy.api.v2.RouteConfiguration"; constexpr char kCdsV2TypeUrl[] = "type.googleapis.com/envoy.api.v2.Cluster"; constexpr char kEdsV2TypeUrl[] = - "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment"; + "type.googleapis.com/envoy.api.v2.ClusterLoadAssignment"; -constexpr char kDefaultLocalityRegion[] = "xds_default_locality_region"; -constexpr char kDefaultLocalityZone[] = "xds_default_locality_zone"; -constexpr char kLbDropType[] = "lb"; -constexpr char kThrottleDropType[] = "throttle"; +constexpr char kDefaultLocalityRegion[] = "xds_default_locality_region"; +constexpr char kDefaultLocalityZone[] = "xds_default_locality_zone"; +constexpr char kLbDropType[] = "lb"; +constexpr char kThrottleDropType[] = "throttle"; constexpr char kServerName[] = "server.example.com"; constexpr char kDefaultRouteConfigurationName[] = "route_config_name"; constexpr char kDefaultClusterName[] = "cluster_name"; constexpr char kDefaultEdsServiceName[] = "eds_service_name"; -constexpr int kDefaultLocalityWeight = 3; -constexpr int kDefaultLocalityPriority = 0; - +constexpr int kDefaultLocalityWeight = 3; +constexpr int kDefaultLocalityPriority = 0; + constexpr char kRequestMessage[] = "Live long and prosper."; constexpr char kDefaultServiceConfig[] = - "{\n" + "{\n" " \"loadBalancingConfig\":[\n" " { \"does_not_exist\":{} },\n" " { \"eds_experimental\":{\n" @@ -158,22 +158,22 @@ constexpr char kBootstrapFileV3[] = " \"server_features\": [\"xds_v3\"]\n" " }\n" " ],\n" - " \"node\": {\n" - " \"id\": \"xds_end2end_test\",\n" - " \"cluster\": \"test\",\n" - " \"metadata\": {\n" - " \"foo\": \"bar\"\n" - " },\n" - " \"locality\": {\n" - " \"region\": \"corp\",\n" - " \"zone\": \"svl\",\n" - " \"subzone\": \"mp3\"\n" - " }\n" - " }\n" - "}\n"; - + " \"node\": {\n" + " \"id\": \"xds_end2end_test\",\n" + " \"cluster\": \"test\",\n" + " \"metadata\": {\n" + " \"foo\": \"bar\"\n" + " },\n" + " \"locality\": {\n" + " \"region\": \"corp\",\n" + " \"zone\": \"svl\",\n" + " \"subzone\": \"mp3\"\n" + " }\n" + " }\n" + "}\n"; + constexpr char kBootstrapFileV2[] = - "{\n" + "{\n" " \"xds_servers\": [\n" " {\n" " \"server_uri\": \"fake:///xds_server\",\n" @@ -184,7 +184,7 @@ constexpr char kBootstrapFileV2[] = " ]\n" " }\n" " ],\n" - " \"node\": {\n" + " \"node\": {\n" " \"id\": \"xds_end2end_test\",\n" " \"cluster\": \"test\",\n" " \"metadata\": {\n" @@ -195,104 +195,104 @@ constexpr char kBootstrapFileV2[] = " \"zone\": \"svl\",\n" " \"subzone\": \"mp3\"\n" " }\n" - " }\n" - "}\n"; - + " }\n" + "}\n"; + char* g_bootstrap_file_v3; char* g_bootstrap_file_v2; - -void WriteBootstrapFiles() { - char* bootstrap_file; + +void WriteBootstrapFiles() { + char* bootstrap_file; FILE* out = gpr_tmpfile("xds_bootstrap_v3", &bootstrap_file); fputs(kBootstrapFileV3, out); - fclose(out); + fclose(out); g_bootstrap_file_v3 = bootstrap_file; out = gpr_tmpfile("xds_bootstrap_v2", &bootstrap_file); fputs(kBootstrapFileV2, out); - fclose(out); + fclose(out); g_bootstrap_file_v2 = bootstrap_file; -} - -// Helper class to minimize the number of unique ports we use for this test. -class PortSaver { - public: - int GetPort() { - if (idx_ >= ports_.size()) { - ports_.push_back(grpc_pick_unused_port_or_die()); - } - return ports_[idx_++]; - } - - void Reset() { idx_ = 0; } - - private: - std::vector<int> ports_; - size_t idx_ = 0; -}; - -PortSaver* g_port_saver = nullptr; - -template <typename ServiceType> -class CountedService : public ServiceType { - public: - size_t request_count() { - grpc_core::MutexLock lock(&mu_); - return request_count_; - } - - size_t response_count() { - grpc_core::MutexLock lock(&mu_); - return response_count_; - } - - void IncreaseResponseCount() { - grpc_core::MutexLock lock(&mu_); - ++response_count_; - } - void IncreaseRequestCount() { - grpc_core::MutexLock lock(&mu_); - ++request_count_; - } - - void ResetCounters() { - grpc_core::MutexLock lock(&mu_); - request_count_ = 0; - response_count_ = 0; - } - +} + +// Helper class to minimize the number of unique ports we use for this test. +class PortSaver { + public: + int GetPort() { + if (idx_ >= ports_.size()) { + ports_.push_back(grpc_pick_unused_port_or_die()); + } + return ports_[idx_++]; + } + + void Reset() { idx_ = 0; } + + private: + std::vector<int> ports_; + size_t idx_ = 0; +}; + +PortSaver* g_port_saver = nullptr; + +template <typename ServiceType> +class CountedService : public ServiceType { + public: + size_t request_count() { + grpc_core::MutexLock lock(&mu_); + return request_count_; + } + + size_t response_count() { + grpc_core::MutexLock lock(&mu_); + return response_count_; + } + + void IncreaseResponseCount() { + grpc_core::MutexLock lock(&mu_); + ++response_count_; + } + void IncreaseRequestCount() { + grpc_core::MutexLock lock(&mu_); + ++request_count_; + } + + void ResetCounters() { + grpc_core::MutexLock lock(&mu_); + request_count_ = 0; + response_count_ = 0; + } + private: - grpc_core::Mutex mu_; - size_t request_count_ = 0; - size_t response_count_ = 0; -}; - -const char g_kCallCredsMdKey[] = "Balancer should not ..."; -const char g_kCallCredsMdValue[] = "... receive me"; - + grpc_core::Mutex mu_; + size_t request_count_ = 0; + size_t response_count_ = 0; +}; + +const char g_kCallCredsMdKey[] = "Balancer should not ..."; +const char g_kCallCredsMdValue[] = "... receive me"; + template <typename RpcService> class BackendServiceImpl : public CountedService<TestMultipleServiceImpl<RpcService>> { - public: - BackendServiceImpl() {} - - Status Echo(ServerContext* context, const EchoRequest* request, - EchoResponse* response) override { - // Backend should receive the call credentials metadata. - auto call_credentials_entry = - context->client_metadata().find(g_kCallCredsMdKey); - EXPECT_NE(call_credentials_entry, context->client_metadata().end()); - if (call_credentials_entry != context->client_metadata().end()) { - EXPECT_EQ(call_credentials_entry->second, g_kCallCredsMdValue); - } + public: + BackendServiceImpl() {} + + Status Echo(ServerContext* context, const EchoRequest* request, + EchoResponse* response) override { + // Backend should receive the call credentials metadata. + auto call_credentials_entry = + context->client_metadata().find(g_kCallCredsMdKey); + EXPECT_NE(call_credentials_entry, context->client_metadata().end()); + if (call_credentials_entry != context->client_metadata().end()) { + EXPECT_EQ(call_credentials_entry->second, g_kCallCredsMdValue); + } CountedService<TestMultipleServiceImpl<RpcService>>::IncreaseRequestCount(); const auto status = TestMultipleServiceImpl<RpcService>::Echo(context, request, response); CountedService< TestMultipleServiceImpl<RpcService>>::IncreaseResponseCount(); - AddClient(context->peer()); - return status; - } - + AddClient(context->peer()); + return status; + } + Status Echo1(ServerContext* context, const EchoRequest* request, EchoResponse* response) override { return Echo(context, request, response); @@ -303,40 +303,40 @@ class BackendServiceImpl return Echo(context, request, response); } - void Start() {} - void Shutdown() {} - + void Start() {} + void Shutdown() {} + std::set<TString> clients() { - grpc_core::MutexLock lock(&clients_mu_); - return clients_; - } - - private: + grpc_core::MutexLock lock(&clients_mu_); + return clients_; + } + + private: void AddClient(const TString& client) { - grpc_core::MutexLock lock(&clients_mu_); - clients_.insert(client); - } - - grpc_core::Mutex clients_mu_; + grpc_core::MutexLock lock(&clients_mu_); + clients_.insert(client); + } + + grpc_core::Mutex clients_mu_; std::set<TString> clients_; -}; - -class ClientStats { - public: - struct LocalityStats { +}; + +class ClientStats { + public: + struct LocalityStats { LocalityStats() {} - // Converts from proto message class. + // Converts from proto message class. template <class UpstreamLocalityStats> - LocalityStats(const UpstreamLocalityStats& upstream_locality_stats) - : total_successful_requests( - upstream_locality_stats.total_successful_requests()), - total_requests_in_progress( - upstream_locality_stats.total_requests_in_progress()), - total_error_requests(upstream_locality_stats.total_error_requests()), - total_issued_requests( - upstream_locality_stats.total_issued_requests()) {} - + LocalityStats(const UpstreamLocalityStats& upstream_locality_stats) + : total_successful_requests( + upstream_locality_stats.total_successful_requests()), + total_requests_in_progress( + upstream_locality_stats.total_requests_in_progress()), + total_error_requests(upstream_locality_stats.total_error_requests()), + total_issued_requests( + upstream_locality_stats.total_issued_requests()) {} + LocalityStats& operator+=(const LocalityStats& other) { total_successful_requests += other.total_successful_requests; total_requests_in_progress += other.total_requests_in_progress; @@ -349,69 +349,69 @@ class ClientStats { uint64_t total_requests_in_progress = 0; uint64_t total_error_requests = 0; uint64_t total_issued_requests = 0; - }; - + }; + ClientStats() {} - // Converts from proto message class. + // Converts from proto message class. template <class ClusterStats> explicit ClientStats(const ClusterStats& cluster_stats) : cluster_name_(cluster_stats.cluster_name()), total_dropped_requests_(cluster_stats.total_dropped_requests()) { - for (const auto& input_locality_stats : - cluster_stats.upstream_locality_stats()) { - locality_stats_.emplace(input_locality_stats.locality().sub_zone(), - LocalityStats(input_locality_stats)); - } - for (const auto& input_dropped_requests : - cluster_stats.dropped_requests()) { - dropped_requests_.emplace(input_dropped_requests.category(), - input_dropped_requests.dropped_count()); - } - } - + for (const auto& input_locality_stats : + cluster_stats.upstream_locality_stats()) { + locality_stats_.emplace(input_locality_stats.locality().sub_zone(), + LocalityStats(input_locality_stats)); + } + for (const auto& input_dropped_requests : + cluster_stats.dropped_requests()) { + dropped_requests_.emplace(input_dropped_requests.category(), + input_dropped_requests.dropped_count()); + } + } + const TString& cluster_name() const { return cluster_name_; } const std::map<TString, LocalityStats>& locality_stats() const { return locality_stats_; } - uint64_t total_successful_requests() const { - uint64_t sum = 0; - for (auto& p : locality_stats_) { - sum += p.second.total_successful_requests; - } - return sum; - } - uint64_t total_requests_in_progress() const { - uint64_t sum = 0; - for (auto& p : locality_stats_) { - sum += p.second.total_requests_in_progress; - } - return sum; - } - uint64_t total_error_requests() const { - uint64_t sum = 0; - for (auto& p : locality_stats_) { - sum += p.second.total_error_requests; - } - return sum; - } - uint64_t total_issued_requests() const { - uint64_t sum = 0; - for (auto& p : locality_stats_) { - sum += p.second.total_issued_requests; - } - return sum; - } - - uint64_t total_dropped_requests() const { return total_dropped_requests_; } + uint64_t total_successful_requests() const { + uint64_t sum = 0; + for (auto& p : locality_stats_) { + sum += p.second.total_successful_requests; + } + return sum; + } + uint64_t total_requests_in_progress() const { + uint64_t sum = 0; + for (auto& p : locality_stats_) { + sum += p.second.total_requests_in_progress; + } + return sum; + } + uint64_t total_error_requests() const { + uint64_t sum = 0; + for (auto& p : locality_stats_) { + sum += p.second.total_error_requests; + } + return sum; + } + uint64_t total_issued_requests() const { + uint64_t sum = 0; + for (auto& p : locality_stats_) { + sum += p.second.total_issued_requests; + } + return sum; + } + + uint64_t total_dropped_requests() const { return total_dropped_requests_; } uint64_t dropped_requests(const TString& category) const { - auto iter = dropped_requests_.find(category); - GPR_ASSERT(iter != dropped_requests_.end()); - return iter->second; - } - + auto iter = dropped_requests_.find(category); + GPR_ASSERT(iter != dropped_requests_.end()); + return iter->second; + } + ClientStats& operator+=(const ClientStats& other) { for (const auto& p : other.locality_stats_) { locality_stats_[p.first] += p.second; @@ -423,15 +423,15 @@ class ClientStats { return *this; } - private: + private: TString cluster_name_; std::map<TString, LocalityStats> locality_stats_; uint64_t total_dropped_requests_ = 0; std::map<TString, uint64_t> dropped_requests_; -}; - +}; + class AdsServiceImpl : public std::enable_shared_from_this<AdsServiceImpl> { - public: + public: struct ResponseState { enum State { NOT_SENT, SENT, ACKED, NACKED }; State state = NOT_SENT; @@ -439,34 +439,34 @@ class AdsServiceImpl : public std::enable_shared_from_this<AdsServiceImpl> { }; struct EdsResourceArgs { - struct Locality { + struct Locality { Locality(const TString& sub_zone, std::vector<int> ports, - int lb_weight = kDefaultLocalityWeight, - int priority = kDefaultLocalityPriority, + int lb_weight = kDefaultLocalityWeight, + int priority = kDefaultLocalityPriority, std::vector<HealthStatus> health_statuses = {}) - : sub_zone(std::move(sub_zone)), - ports(std::move(ports)), - lb_weight(lb_weight), - priority(priority), - health_statuses(std::move(health_statuses)) {} - + : sub_zone(std::move(sub_zone)), + ports(std::move(ports)), + lb_weight(lb_weight), + priority(priority), + health_statuses(std::move(health_statuses)) {} + const TString sub_zone; - std::vector<int> ports; - int lb_weight; - int priority; + std::vector<int> ports; + int lb_weight; + int priority; std::vector<HealthStatus> health_statuses; - }; - + }; + EdsResourceArgs() = default; explicit EdsResourceArgs(std::vector<Locality> locality_list) - : locality_list(std::move(locality_list)) {} - - std::vector<Locality> locality_list; + : locality_list(std::move(locality_list)) {} + + std::vector<Locality> locality_list; std::map<TString, uint32_t> drop_categories; - FractionalPercent::DenominatorType drop_denominator = - FractionalPercent::MILLION; - }; - + FractionalPercent::DenominatorType drop_denominator = + FractionalPercent::MILLION; + }; + explicit AdsServiceImpl(bool enable_load_reporting) : v2_rpc_service_(this, /*is_v2=*/true), v3_rpc_service_(this, /*is_v2=*/false) { @@ -500,8 +500,8 @@ class AdsServiceImpl : public std::enable_shared_from_this<AdsServiceImpl> { ::envoy::service::discovery::v2::AggregatedDiscoveryService::Service* v2_rpc_service() { return &v2_rpc_service_; - } - + } + ::envoy::service::discovery::v3::AggregatedDiscoveryService::Service* v3_rpc_service() { return &v3_rpc_service_; @@ -524,10 +524,10 @@ class AdsServiceImpl : public std::enable_shared_from_this<AdsServiceImpl> { } ResponseState cds_response_state() { - grpc_core::MutexLock lock(&ads_mu_); + grpc_core::MutexLock lock(&ads_mu_); return resource_type_response_state_[kCdsTypeUrl]; - } - + } + ResponseState eds_response_state() { grpc_core::MutexLock lock(&ads_mu_); return resource_type_response_state_[kEdsTypeUrl]; @@ -611,44 +611,44 @@ class AdsServiceImpl : public std::enable_shared_from_this<AdsServiceImpl> { static ClusterLoadAssignment BuildEdsResource( const EdsResourceArgs& args, const char* eds_service_name = kDefaultEdsServiceName) { - ClusterLoadAssignment assignment; + ClusterLoadAssignment assignment; assignment.set_cluster_name(eds_service_name); - for (const auto& locality : args.locality_list) { - auto* endpoints = assignment.add_endpoints(); - endpoints->mutable_load_balancing_weight()->set_value(locality.lb_weight); - endpoints->set_priority(locality.priority); - endpoints->mutable_locality()->set_region(kDefaultLocalityRegion); - endpoints->mutable_locality()->set_zone(kDefaultLocalityZone); - endpoints->mutable_locality()->set_sub_zone(locality.sub_zone); - for (size_t i = 0; i < locality.ports.size(); ++i) { - const int& port = locality.ports[i]; - auto* lb_endpoints = endpoints->add_lb_endpoints(); - if (locality.health_statuses.size() > i && + for (const auto& locality : args.locality_list) { + auto* endpoints = assignment.add_endpoints(); + endpoints->mutable_load_balancing_weight()->set_value(locality.lb_weight); + endpoints->set_priority(locality.priority); + endpoints->mutable_locality()->set_region(kDefaultLocalityRegion); + endpoints->mutable_locality()->set_zone(kDefaultLocalityZone); + endpoints->mutable_locality()->set_sub_zone(locality.sub_zone); + for (size_t i = 0; i < locality.ports.size(); ++i) { + const int& port = locality.ports[i]; + auto* lb_endpoints = endpoints->add_lb_endpoints(); + if (locality.health_statuses.size() > i && locality.health_statuses[i] != HealthStatus::UNKNOWN) { - lb_endpoints->set_health_status(locality.health_statuses[i]); - } - auto* endpoint = lb_endpoints->mutable_endpoint(); - auto* address = endpoint->mutable_address(); - auto* socket_address = address->mutable_socket_address(); - socket_address->set_address("127.0.0.1"); - socket_address->set_port_value(port); - } - } - if (!args.drop_categories.empty()) { - auto* policy = assignment.mutable_policy(); - for (const auto& p : args.drop_categories) { + lb_endpoints->set_health_status(locality.health_statuses[i]); + } + auto* endpoint = lb_endpoints->mutable_endpoint(); + auto* address = endpoint->mutable_address(); + auto* socket_address = address->mutable_socket_address(); + socket_address->set_address("127.0.0.1"); + socket_address->set_port_value(port); + } + } + if (!args.drop_categories.empty()) { + auto* policy = assignment.mutable_policy(); + for (const auto& p : args.drop_categories) { const TString& name = p.first; - const uint32_t parts_per_million = p.second; - auto* drop_overload = policy->add_drop_overloads(); - drop_overload->set_category(name); - auto* drop_percentage = drop_overload->mutable_drop_percentage(); - drop_percentage->set_numerator(parts_per_million); - drop_percentage->set_denominator(args.drop_denominator); - } - } + const uint32_t parts_per_million = p.second; + auto* drop_overload = policy->add_drop_overloads(); + drop_overload->set_category(name); + auto* drop_percentage = drop_overload->mutable_drop_percentage(); + drop_percentage->set_numerator(parts_per_million); + drop_percentage->set_denominator(args.drop_denominator); + } + } return assignment; - } - + } + void Start() { grpc_core::MutexLock lock(&ads_mu_); ads_done_ = false; @@ -663,24 +663,24 @@ class AdsServiceImpl : public std::enable_shared_from_this<AdsServiceImpl> { gpr_log(GPR_INFO, "ADS[%p]: shut down", this); } - void NotifyDoneWithAdsCall() { - grpc_core::MutexLock lock(&ads_mu_); - NotifyDoneWithAdsCallLocked(); - } - - void NotifyDoneWithAdsCallLocked() { - if (!ads_done_) { - ads_done_ = true; - ads_cond_.Broadcast(); - } - } - + void NotifyDoneWithAdsCall() { + grpc_core::MutexLock lock(&ads_mu_); + NotifyDoneWithAdsCallLocked(); + } + + void NotifyDoneWithAdsCallLocked() { + if (!ads_done_) { + ads_done_ = true; + ads_cond_.Broadcast(); + } + } + std::set<TString> clients() { grpc_core::MutexLock lock(&clients_mu_); return clients_; } - private: + private: // A queue of resource type/name pairs that have changed since the client // subscribed to them. using UpdateQueue = std::deque< @@ -1119,10 +1119,10 @@ class AdsServiceImpl : public std::enable_shared_from_this<AdsServiceImpl> { std::atomic_bool seen_v2_client_{false}; std::atomic_bool seen_v3_client_{false}; - grpc_core::CondVar ads_cond_; - // Protect the members below. - grpc_core::Mutex ads_mu_; - bool ads_done_ = false; + grpc_core::CondVar ads_cond_; + // Protect the members below. + grpc_core::Mutex ads_mu_; + bool ads_done_ = false; Listener default_listener_; RouteConfiguration default_route_config_; Cluster default_cluster_; @@ -1138,22 +1138,22 @@ class AdsServiceImpl : public std::enable_shared_from_this<AdsServiceImpl> { grpc_core::Mutex clients_mu_; std::set<TString> clients_; -}; - +}; + class LrsServiceImpl : public std::enable_shared_from_this<LrsServiceImpl> { - public: - explicit LrsServiceImpl(int client_load_reporting_interval_seconds) + public: + explicit LrsServiceImpl(int client_load_reporting_interval_seconds) : v2_rpc_service_(this), v3_rpc_service_(this), client_load_reporting_interval_seconds_( client_load_reporting_interval_seconds), cluster_names_({kDefaultClusterName}) {} - + ::envoy::service::load_stats::v2::LoadReportingService::Service* v2_rpc_service() { return &v2_rpc_service_; - } - + } + ::envoy::service::load_stats::v3::LoadReportingService::Service* v3_rpc_service() { return &v3_rpc_service_; @@ -1175,21 +1175,21 @@ class LrsServiceImpl : public std::enable_shared_from_this<LrsServiceImpl> { cluster_names_ = cluster_names; } - void Start() { + void Start() { lrs_done_ = false; result_queue_.clear(); - } - - void Shutdown() { - { - grpc_core::MutexLock lock(&lrs_mu_); - NotifyDoneWithLrsCallLocked(); - } - gpr_log(GPR_INFO, "LRS[%p]: shut down", this); - } - + } + + void Shutdown() { + { + grpc_core::MutexLock lock(&lrs_mu_); + NotifyDoneWithLrsCallLocked(); + } + gpr_log(GPR_INFO, "LRS[%p]: shut down", this); + } + std::vector<ClientStats> WaitForLoadReport() { - grpc_core::MutexLock lock(&load_report_mu_); + grpc_core::MutexLock lock(&load_report_mu_); grpc_core::CondVar cv; if (result_queue_.empty()) { load_report_cond_ = &cv; @@ -1200,13 +1200,13 @@ class LrsServiceImpl : public std::enable_shared_from_this<LrsServiceImpl> { std::vector<ClientStats> result = std::move(result_queue_.front()); result_queue_.pop_front(); return result; - } - - void NotifyDoneWithLrsCall() { - grpc_core::MutexLock lock(&lrs_mu_); - NotifyDoneWithLrsCallLocked(); - } - + } + + void NotifyDoneWithLrsCall() { + grpc_core::MutexLock lock(&lrs_mu_); + NotifyDoneWithLrsCallLocked(); + } + private: template <class RpcApi, class LoadStatsRequest, class LoadStatsResponse> class RpcService : public CountedService<typename RpcApi::Service> { @@ -1272,13 +1272,13 @@ class LrsServiceImpl : public std::enable_shared_from_this<LrsServiceImpl> { LrsServiceImpl* parent_; }; - void NotifyDoneWithLrsCallLocked() { + void NotifyDoneWithLrsCallLocked() { if (!lrs_done_) { lrs_done_ = true; - lrs_cv_.Broadcast(); - } - } - + lrs_cv_.Broadcast(); + } + } + RpcService<::envoy::service::load_stats::v2::LoadReportingService, ::envoy::service::load_stats::v2::LoadStatsRequest, ::envoy::service::load_stats::v2::LoadStatsResponse> @@ -1288,80 +1288,80 @@ class LrsServiceImpl : public std::enable_shared_from_this<LrsServiceImpl> { ::envoy::service::load_stats::v3::LoadStatsResponse> v3_rpc_service_; - const int client_load_reporting_interval_seconds_; + const int client_load_reporting_interval_seconds_; bool send_all_clusters_ = false; std::set<TString> cluster_names_; - - grpc_core::CondVar lrs_cv_; + + grpc_core::CondVar lrs_cv_; grpc_core::Mutex lrs_mu_; // Protects lrs_done_. bool lrs_done_ = false; - + grpc_core::Mutex load_report_mu_; // Protects the members below. grpc_core::CondVar* load_report_cond_ = nullptr; std::deque<std::vector<ClientStats>> result_queue_; -}; - -class TestType { - public: +}; + +class TestType { + public: TestType(bool use_xds_resolver, bool enable_load_reporting, bool enable_rds_testing = false, bool use_v2 = false) - : use_xds_resolver_(use_xds_resolver), + : use_xds_resolver_(use_xds_resolver), enable_load_reporting_(enable_load_reporting), enable_rds_testing_(enable_rds_testing), use_v2_(use_v2) {} - - bool use_xds_resolver() const { return use_xds_resolver_; } - bool enable_load_reporting() const { return enable_load_reporting_; } + + bool use_xds_resolver() const { return use_xds_resolver_; } + bool enable_load_reporting() const { return enable_load_reporting_; } bool enable_rds_testing() const { return enable_rds_testing_; } bool use_v2() const { return use_v2_; } - + TString AsString() const { TString retval = (use_xds_resolver_ ? "XdsResolver" : "FakeResolver"); retval += (use_v2_ ? "V2" : "V3"); - if (enable_load_reporting_) retval += "WithLoadReporting"; + if (enable_load_reporting_) retval += "WithLoadReporting"; if (enable_rds_testing_) retval += "Rds"; - return retval; - } - - private: - const bool use_xds_resolver_; - const bool enable_load_reporting_; + return retval; + } + + private: + const bool use_xds_resolver_; + const bool enable_load_reporting_; const bool enable_rds_testing_; const bool use_v2_; -}; - -class XdsEnd2endTest : public ::testing::TestWithParam<TestType> { - protected: - XdsEnd2endTest(size_t num_backends, size_t num_balancers, +}; + +class XdsEnd2endTest : public ::testing::TestWithParam<TestType> { + protected: + XdsEnd2endTest(size_t num_backends, size_t num_balancers, int client_load_reporting_interval_seconds = 100) : num_backends_(num_backends), - num_balancers_(num_balancers), - client_load_reporting_interval_seconds_( - client_load_reporting_interval_seconds) {} - - static void SetUpTestCase() { - // Make the backup poller poll very frequently in order to pick up - // updates from all the subchannels's FDs. - GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); -#if TARGET_OS_IPHONE - // Workaround Apple CFStream bug - gpr_setenv("grpc_cfstream", "0"); -#endif - grpc_init(); - } - - static void TearDownTestCase() { grpc_shutdown(); } - - void SetUp() override { + num_balancers_(num_balancers), + client_load_reporting_interval_seconds_( + client_load_reporting_interval_seconds) {} + + static void SetUpTestCase() { + // Make the backup poller poll very frequently in order to pick up + // updates from all the subchannels's FDs. + GPR_GLOBAL_CONFIG_SET(grpc_client_channel_backup_poll_interval_ms, 1); +#if TARGET_OS_IPHONE + // Workaround Apple CFStream bug + gpr_setenv("grpc_cfstream", "0"); +#endif + grpc_init(); + } + + static void TearDownTestCase() { grpc_shutdown(); } + + void SetUp() override { gpr_setenv("GRPC_XDS_EXPERIMENTAL_V3_SUPPORT", "true"); gpr_setenv("GRPC_XDS_BOOTSTRAP", GetParam().use_v2() ? g_bootstrap_file_v2 : g_bootstrap_file_v3); - g_port_saver->Reset(); - response_generator_ = - grpc_core::MakeRefCounted<grpc_core::FakeResolverResponseGenerator>(); + g_port_saver->Reset(); + response_generator_ = + grpc_core::MakeRefCounted<grpc_core::FakeResolverResponseGenerator>(); // Inject xDS channel response generator. - lb_channel_response_generator_ = - grpc_core::MakeRefCounted<grpc_core::FakeResolverResponseGenerator>(); + lb_channel_response_generator_ = + grpc_core::MakeRefCounted<grpc_core::FakeResolverResponseGenerator>(); xds_channel_args_to_add_.emplace_back( grpc_core::FakeResolverResponseGenerator::MakeChannelArg( lb_channel_response_generator_.get())); @@ -1381,14 +1381,14 @@ class XdsEnd2endTest : public ::testing::TestWithParam<TestType> { // ensures that each test can independently set the global channel // args for the xDS channel. grpc_core::internal::UnsetGlobalXdsClientForTest(); - // Start the backends. - for (size_t i = 0; i < num_backends_; ++i) { - backends_.emplace_back(new BackendServerThread); + // Start the backends. + for (size_t i = 0; i < num_backends_; ++i) { + backends_.emplace_back(new BackendServerThread); backends_.back()->Start(); - } - // Start the load balancers. - for (size_t i = 0; i < num_balancers_; ++i) { - balancers_.emplace_back( + } + // Start the load balancers. + for (size_t i = 0; i < num_balancers_; ++i) { + balancers_.emplace_back( new BalancerServerThread(GetParam().enable_load_reporting() ? client_load_reporting_interval_seconds_ : 0)); @@ -1396,34 +1396,34 @@ class XdsEnd2endTest : public ::testing::TestWithParam<TestType> { if (GetParam().enable_rds_testing()) { balancers_[i]->ads_service()->SetLdsToUseDynamicRds(); } - } - ResetStub(); - } - + } + ResetStub(); + } + const char* DefaultEdsServiceName() const { return GetParam().use_xds_resolver() ? kDefaultEdsServiceName : kServerName; } - void TearDown() override { - ShutdownAllBackends(); - for (auto& balancer : balancers_) balancer->Shutdown(); + void TearDown() override { + ShutdownAllBackends(); + for (auto& balancer : balancers_) balancer->Shutdown(); // Clear global xDS channel args, since they will go out of scope // when this test object is destroyed. grpc_core::internal::SetXdsChannelArgsForTest(nullptr); - } - - void StartAllBackends() { + } + + void StartAllBackends() { for (auto& backend : backends_) backend->Start(); - } - + } + void StartBackend(size_t index) { backends_[index]->Start(); } - - void ShutdownAllBackends() { - for (auto& backend : backends_) backend->Shutdown(); - } - - void ShutdownBackend(size_t index) { backends_[index]->Shutdown(); } - + + void ShutdownAllBackends() { + for (auto& backend : backends_) backend->Shutdown(); + } + + void ShutdownBackend(size_t index) { backends_[index]->Shutdown(); } + void ResetStub(int failover_timeout = 0) { channel_ = CreateChannel(failover_timeout); stub_ = grpc::testing::EchoTestService::NewStub(channel_); @@ -1433,32 +1433,32 @@ class XdsEnd2endTest : public ::testing::TestWithParam<TestType> { std::shared_ptr<Channel> CreateChannel( int failover_timeout = 0, const char* server_name = kServerName) { - ChannelArguments args; - if (failover_timeout > 0) { + ChannelArguments args; + if (failover_timeout > 0) { args.SetInt(GRPC_ARG_PRIORITY_FAILOVER_TIMEOUT_MS, failover_timeout); - } - // If the parent channel is using the fake resolver, we inject the + } + // If the parent channel is using the fake resolver, we inject the // response generator here. if (!GetParam().use_xds_resolver()) { args.SetPointer(GRPC_ARG_FAKE_RESOLVER_RESPONSE_GENERATOR, response_generator_.get()); - } + } TString uri = y_absl::StrCat( GetParam().use_xds_resolver() ? "xds" : "fake", ":///", server_name); - // TODO(dgq): templatize tests to run everything using both secure and - // insecure channel credentials. - grpc_channel_credentials* channel_creds = - grpc_fake_transport_security_credentials_create(); - grpc_call_credentials* call_creds = grpc_md_only_test_credentials_create( - g_kCallCredsMdKey, g_kCallCredsMdValue, false); - std::shared_ptr<ChannelCredentials> creds( - new SecureChannelCredentials(grpc_composite_channel_credentials_create( - channel_creds, call_creds, nullptr))); - call_creds->Unref(); - channel_creds->Unref(); + // TODO(dgq): templatize tests to run everything using both secure and + // insecure channel credentials. + grpc_channel_credentials* channel_creds = + grpc_fake_transport_security_credentials_create(); + grpc_call_credentials* call_creds = grpc_md_only_test_credentials_create( + g_kCallCredsMdKey, g_kCallCredsMdValue, false); + std::shared_ptr<ChannelCredentials> creds( + new SecureChannelCredentials(grpc_composite_channel_credentials_create( + channel_creds, call_creds, nullptr))); + call_creds->Unref(); + channel_creds->Unref(); return ::grpc::CreateCustomChannel(uri, creds, args); - } - + } + enum RpcService { SERVICE_ECHO, SERVICE_ECHO1, @@ -1525,15 +1525,15 @@ class XdsEnd2endTest : public ::testing::TestWithParam<TestType> { case METHOD_ECHO2: return (*stub)->Echo2(context, request, response); } - } - + } + void ResetBackendCounters(size_t start_index = 0, size_t stop_index = 0) { - if (stop_index == 0) stop_index = backends_.size(); - for (size_t i = start_index; i < stop_index; ++i) { + if (stop_index == 0) stop_index = backends_.size(); + for (size_t i = start_index; i < stop_index; ++i) { backends_[i]->backend_service()->ResetCounters(); backends_[i]->backend_service1()->ResetCounters(); backends_[i]->backend_service2()->ResetCounters(); - } + } } bool SeenAllBackends(size_t start_index = 0, size_t stop_index = 0, @@ -1555,149 +1555,149 @@ class XdsEnd2endTest : public ::testing::TestWithParam<TestType> { break; } } - return true; - } - - void SendRpcAndCount(int* num_total, int* num_ok, int* num_failure, + return true; + } + + void SendRpcAndCount(int* num_total, int* num_ok, int* num_failure, int* num_drops, const RpcOptions& rpc_options = RpcOptions()) { const Status status = SendRpc(rpc_options); - if (status.ok()) { - ++*num_ok; - } else { - if (status.error_message() == "Call dropped by load balancing policy") { - ++*num_drops; - } else { - ++*num_failure; - } - } - ++*num_total; - } - + if (status.ok()) { + ++*num_ok; + } else { + if (status.error_message() == "Call dropped by load balancing policy") { + ++*num_drops; + } else { + ++*num_failure; + } + } + ++*num_total; + } + std::tuple<int, int, int> WaitForAllBackends( size_t start_index = 0, size_t stop_index = 0, bool reset_counters = true, const RpcOptions& rpc_options = RpcOptions(), bool allow_failures = false) { - int num_ok = 0; - int num_failure = 0; - int num_drops = 0; - int num_total = 0; + int num_ok = 0; + int num_failure = 0; + int num_drops = 0; + int num_total = 0; while (!SeenAllBackends(start_index, stop_index, rpc_options)) { SendRpcAndCount(&num_total, &num_ok, &num_failure, &num_drops, rpc_options); - } + } if (reset_counters) ResetBackendCounters(); - gpr_log(GPR_INFO, - "Performed %d warm up requests against the backends. " - "%d succeeded, %d failed, %d dropped.", - num_total, num_ok, num_failure, num_drops); + gpr_log(GPR_INFO, + "Performed %d warm up requests against the backends. " + "%d succeeded, %d failed, %d dropped.", + num_total, num_ok, num_failure, num_drops); if (!allow_failures) EXPECT_EQ(num_failure, 0); - return std::make_tuple(num_ok, num_failure, num_drops); - } - + return std::make_tuple(num_ok, num_failure, num_drops); + } + void WaitForBackend(size_t backend_idx, bool reset_counters = true, bool require_success = false) { - gpr_log(GPR_INFO, "========= WAITING FOR BACKEND %lu ==========", - static_cast<unsigned long>(backend_idx)); - do { + gpr_log(GPR_INFO, "========= WAITING FOR BACKEND %lu ==========", + static_cast<unsigned long>(backend_idx)); + do { Status status = SendRpc(); if (require_success) { EXPECT_TRUE(status.ok()) << "code=" << status.error_code() << " message=" << status.error_message(); } - } while (backends_[backend_idx]->backend_service()->request_count() == 0); - if (reset_counters) ResetBackendCounters(); - gpr_log(GPR_INFO, "========= BACKEND %lu READY ==========", - static_cast<unsigned long>(backend_idx)); - } - - grpc_core::ServerAddressList CreateAddressListFromPortList( - const std::vector<int>& ports) { - grpc_core::ServerAddressList addresses; - for (int port : ports) { + } while (backends_[backend_idx]->backend_service()->request_count() == 0); + if (reset_counters) ResetBackendCounters(); + gpr_log(GPR_INFO, "========= BACKEND %lu READY ==========", + static_cast<unsigned long>(backend_idx)); + } + + grpc_core::ServerAddressList CreateAddressListFromPortList( + const std::vector<int>& ports) { + grpc_core::ServerAddressList addresses; + for (int port : ports) { TString lb_uri_str = y_absl::StrCat("ipv4:127.0.0.1:", port); grpc_uri* lb_uri = grpc_uri_parse(lb_uri_str.c_str(), true); - GPR_ASSERT(lb_uri != nullptr); - grpc_resolved_address address; - GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); - addresses.emplace_back(address.addr, address.len, nullptr); - grpc_uri_destroy(lb_uri); - } - return addresses; - } - + GPR_ASSERT(lb_uri != nullptr); + grpc_resolved_address address; + GPR_ASSERT(grpc_parse_uri(lb_uri, &address)); + addresses.emplace_back(address.addr, address.len, nullptr); + grpc_uri_destroy(lb_uri); + } + return addresses; + } + void SetNextResolution(const std::vector<int>& ports) { - if (GetParam().use_xds_resolver()) return; // Not used with xds resolver. - grpc_core::ExecCtx exec_ctx; - grpc_core::Resolver::Result result; - result.addresses = CreateAddressListFromPortList(ports); - grpc_error* error = GRPC_ERROR_NONE; - const char* service_config_json = - GetParam().enable_load_reporting() + if (GetParam().use_xds_resolver()) return; // Not used with xds resolver. + grpc_core::ExecCtx exec_ctx; + grpc_core::Resolver::Result result; + result.addresses = CreateAddressListFromPortList(ports); + grpc_error* error = GRPC_ERROR_NONE; + const char* service_config_json = + GetParam().enable_load_reporting() ? kDefaultServiceConfig : kDefaultServiceConfigWithoutLoadReporting; - result.service_config = + result.service_config = grpc_core::ServiceConfig::Create(nullptr, service_config_json, &error); ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); ASSERT_NE(result.service_config.get(), nullptr); - response_generator_->SetResponse(std::move(result)); - } - - void SetNextResolutionForLbChannelAllBalancers( - const char* service_config_json = nullptr, + response_generator_->SetResponse(std::move(result)); + } + + void SetNextResolutionForLbChannelAllBalancers( + const char* service_config_json = nullptr, const char* expected_targets = nullptr) { - std::vector<int> ports; - for (size_t i = 0; i < balancers_.size(); ++i) { - ports.emplace_back(balancers_[i]->port()); - } + std::vector<int> ports; + for (size_t i = 0; i < balancers_.size(); ++i) { + ports.emplace_back(balancers_[i]->port()); + } SetNextResolutionForLbChannel(ports, service_config_json, expected_targets); - } - + } + void SetNextResolutionForLbChannel(const std::vector<int>& ports, const char* service_config_json = nullptr, const char* expected_targets = nullptr) { - grpc_core::ExecCtx exec_ctx; - grpc_core::Resolver::Result result; - result.addresses = CreateAddressListFromPortList(ports); - if (service_config_json != nullptr) { - grpc_error* error = GRPC_ERROR_NONE; + grpc_core::ExecCtx exec_ctx; + grpc_core::Resolver::Result result; + result.addresses = CreateAddressListFromPortList(ports); + if (service_config_json != nullptr) { + grpc_error* error = GRPC_ERROR_NONE; result.service_config = grpc_core::ServiceConfig::Create( nullptr, service_config_json, &error); ASSERT_NE(result.service_config.get(), nullptr); ASSERT_EQ(error, GRPC_ERROR_NONE) << grpc_error_string(error); - } + } if (expected_targets != nullptr) { grpc_arg expected_targets_arg = grpc_channel_arg_string_create( const_cast<char*>(GRPC_ARG_FAKE_SECURITY_EXPECTED_TARGETS), const_cast<char*>(expected_targets)); result.args = grpc_channel_args_copy_and_add(nullptr, &expected_targets_arg, 1); - } + } lb_channel_response_generator_->SetResponse(std::move(result)); - } - - void SetNextReresolutionResponse(const std::vector<int>& ports) { - grpc_core::ExecCtx exec_ctx; - grpc_core::Resolver::Result result; - result.addresses = CreateAddressListFromPortList(ports); - response_generator_->SetReresolutionResponse(std::move(result)); - } - - const std::vector<int> GetBackendPorts(size_t start_index = 0, - size_t stop_index = 0) const { - if (stop_index == 0) stop_index = backends_.size(); - std::vector<int> backend_ports; - for (size_t i = start_index; i < stop_index; ++i) { - backend_ports.push_back(backends_[i]->port()); - } - return backend_ports; - } - + } + + void SetNextReresolutionResponse(const std::vector<int>& ports) { + grpc_core::ExecCtx exec_ctx; + grpc_core::Resolver::Result result; + result.addresses = CreateAddressListFromPortList(ports); + response_generator_->SetReresolutionResponse(std::move(result)); + } + + const std::vector<int> GetBackendPorts(size_t start_index = 0, + size_t stop_index = 0) const { + if (stop_index == 0) stop_index = backends_.size(); + std::vector<int> backend_ports; + for (size_t i = start_index; i < stop_index; ++i) { + backend_ports.push_back(backends_[i]->port()); + } + return backend_ports; + } + Status SendRpc(const RpcOptions& rpc_options = RpcOptions(), EchoResponse* response = nullptr) { - const bool local_response = (response == nullptr); - if (local_response) response = new EchoResponse; - EchoRequest request; + const bool local_response = (response == nullptr); + if (local_response) response = new EchoResponse; + EchoRequest request; ClientContext context; for (const auto& metadata : rpc_options.metadata) { context.AddMetadata(metadata.first, metadata.second); @@ -1727,29 +1727,29 @@ class XdsEnd2endTest : public ::testing::TestWithParam<TestType> { SendRpcMethod(&stub2_, rpc_options, &context, request, response); break; } - if (local_response) delete response; - return status; - } - + if (local_response) delete response; + return status; + } + void CheckRpcSendOk(const size_t times = 1, const RpcOptions& rpc_options = RpcOptions()) { - for (size_t i = 0; i < times; ++i) { - EchoResponse response; + for (size_t i = 0; i < times; ++i) { + EchoResponse response; const Status status = SendRpc(rpc_options, &response); - EXPECT_TRUE(status.ok()) << "code=" << status.error_code() - << " message=" << status.error_message(); + EXPECT_TRUE(status.ok()) << "code=" << status.error_code() + << " message=" << status.error_message(); EXPECT_EQ(response.message(), kRequestMessage); - } - } - + } + } + void CheckRpcSendFailure(const size_t times = 1, const RpcOptions& rpc_options = RpcOptions()) { for (size_t i = 0; i < times; ++i) { const Status status = SendRpc(rpc_options); EXPECT_FALSE(status.ok()); } - } - + } + void SetRouteConfiguration(int idx, const RouteConfiguration& route_config) { if (GetParam().enable_rds_testing()) { balancers_[idx]->ads_service()->SetRdsResource(route_config); @@ -1779,69 +1779,69 @@ class XdsEnd2endTest : public ::testing::TestWithParam<TestType> { } protected: - class ServerThread { - public: - ServerThread() : port_(g_port_saver->GetPort()) {} - virtual ~ServerThread(){}; - + class ServerThread { + public: + ServerThread() : port_(g_port_saver->GetPort()) {} + virtual ~ServerThread(){}; + void Start() { - gpr_log(GPR_INFO, "starting %s server on port %d", Type(), port_); - GPR_ASSERT(!running_); - running_ = true; - StartAllServices(); - grpc_core::Mutex mu; - // We need to acquire the lock here in order to prevent the notify_one - // by ServerThread::Serve from firing before the wait below is hit. - grpc_core::MutexLock lock(&mu); - grpc_core::CondVar cond; + gpr_log(GPR_INFO, "starting %s server on port %d", Type(), port_); + GPR_ASSERT(!running_); + running_ = true; + StartAllServices(); + grpc_core::Mutex mu; + // We need to acquire the lock here in order to prevent the notify_one + // by ServerThread::Serve from firing before the wait below is hit. + grpc_core::MutexLock lock(&mu); + grpc_core::CondVar cond; thread_.reset( new std::thread(std::bind(&ServerThread::Serve, this, &mu, &cond))); - cond.Wait(&mu); - gpr_log(GPR_INFO, "%s server startup complete", Type()); - } - + cond.Wait(&mu); + gpr_log(GPR_INFO, "%s server startup complete", Type()); + } + void Serve(grpc_core::Mutex* mu, grpc_core::CondVar* cond) { - // We need to acquire the lock here in order to prevent the notify_one - // below from firing before its corresponding wait is executed. - grpc_core::MutexLock lock(mu); - std::ostringstream server_address; + // We need to acquire the lock here in order to prevent the notify_one + // below from firing before its corresponding wait is executed. + grpc_core::MutexLock lock(mu); + std::ostringstream server_address; server_address << "localhost:" << port_; - ServerBuilder builder; - std::shared_ptr<ServerCredentials> creds(new SecureServerCredentials( - grpc_fake_transport_security_server_credentials_create())); - builder.AddListeningPort(server_address.str(), creds); - RegisterAllServices(&builder); - server_ = builder.BuildAndStart(); - cond->Signal(); - } - - void Shutdown() { - if (!running_) return; - gpr_log(GPR_INFO, "%s about to shutdown", Type()); - ShutdownAllServices(); - server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); - thread_->join(); - gpr_log(GPR_INFO, "%s shutdown completed", Type()); - running_ = false; - } - - int port() const { return port_; } - - private: - virtual void RegisterAllServices(ServerBuilder* builder) = 0; - virtual void StartAllServices() = 0; - virtual void ShutdownAllServices() = 0; - - virtual const char* Type() = 0; - - const int port_; - std::unique_ptr<Server> server_; - std::unique_ptr<std::thread> thread_; - bool running_ = false; - }; - - class BackendServerThread : public ServerThread { - public: + ServerBuilder builder; + std::shared_ptr<ServerCredentials> creds(new SecureServerCredentials( + grpc_fake_transport_security_server_credentials_create())); + builder.AddListeningPort(server_address.str(), creds); + RegisterAllServices(&builder); + server_ = builder.BuildAndStart(); + cond->Signal(); + } + + void Shutdown() { + if (!running_) return; + gpr_log(GPR_INFO, "%s about to shutdown", Type()); + ShutdownAllServices(); + server_->Shutdown(grpc_timeout_milliseconds_to_deadline(0)); + thread_->join(); + gpr_log(GPR_INFO, "%s shutdown completed", Type()); + running_ = false; + } + + int port() const { return port_; } + + private: + virtual void RegisterAllServices(ServerBuilder* builder) = 0; + virtual void StartAllServices() = 0; + virtual void ShutdownAllServices() = 0; + + virtual const char* Type() = 0; + + const int port_; + std::unique_ptr<Server> server_; + std::unique_ptr<std::thread> thread_; + bool running_ = false; + }; + + class BackendServerThread : public ServerThread { + public: BackendServiceImpl<::grpc::testing::EchoTestService::Service>* backend_service() { return &backend_service_; @@ -1854,240 +1854,240 @@ class XdsEnd2endTest : public ::testing::TestWithParam<TestType> { backend_service2() { return &backend_service2_; } - - private: - void RegisterAllServices(ServerBuilder* builder) override { - builder->RegisterService(&backend_service_); + + private: + void RegisterAllServices(ServerBuilder* builder) override { + builder->RegisterService(&backend_service_); builder->RegisterService(&backend_service1_); builder->RegisterService(&backend_service2_); - } - + } + void StartAllServices() override { backend_service_.Start(); backend_service1_.Start(); backend_service2_.Start(); } - + void ShutdownAllServices() override { backend_service_.Shutdown(); backend_service1_.Shutdown(); backend_service2_.Shutdown(); } - - const char* Type() override { return "Backend"; } - + + const char* Type() override { return "Backend"; } + BackendServiceImpl<::grpc::testing::EchoTestService::Service> backend_service_; BackendServiceImpl<::grpc::testing::EchoTest1Service::Service> backend_service1_; BackendServiceImpl<::grpc::testing::EchoTest2Service::Service> backend_service2_; - }; - - class BalancerServerThread : public ServerThread { - public: - explicit BalancerServerThread(int client_load_reporting_interval = 0) + }; + + class BalancerServerThread : public ServerThread { + public: + explicit BalancerServerThread(int client_load_reporting_interval = 0) : ads_service_(new AdsServiceImpl(client_load_reporting_interval > 0)), lrs_service_(new LrsServiceImpl(client_load_reporting_interval)) {} - + AdsServiceImpl* ads_service() { return ads_service_.get(); } LrsServiceImpl* lrs_service() { return lrs_service_.get(); } - - private: - void RegisterAllServices(ServerBuilder* builder) override { + + private: + void RegisterAllServices(ServerBuilder* builder) override { builder->RegisterService(ads_service_->v2_rpc_service()); builder->RegisterService(ads_service_->v3_rpc_service()); builder->RegisterService(lrs_service_->v2_rpc_service()); builder->RegisterService(lrs_service_->v3_rpc_service()); - } - - void StartAllServices() override { + } + + void StartAllServices() override { ads_service_->Start(); lrs_service_->Start(); - } - - void ShutdownAllServices() override { + } + + void ShutdownAllServices() override { ads_service_->Shutdown(); lrs_service_->Shutdown(); - } - - const char* Type() override { return "Balancer"; } - + } + + const char* Type() override { return "Balancer"; } + std::shared_ptr<AdsServiceImpl> ads_service_; std::shared_ptr<LrsServiceImpl> lrs_service_; - }; - - const size_t num_backends_; - const size_t num_balancers_; - const int client_load_reporting_interval_seconds_; - std::shared_ptr<Channel> channel_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; + }; + + const size_t num_backends_; + const size_t num_balancers_; + const int client_load_reporting_interval_seconds_; + std::shared_ptr<Channel> channel_; + std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; std::unique_ptr<grpc::testing::EchoTest1Service::Stub> stub1_; std::unique_ptr<grpc::testing::EchoTest2Service::Stub> stub2_; - std::vector<std::unique_ptr<BackendServerThread>> backends_; - std::vector<std::unique_ptr<BalancerServerThread>> balancers_; - grpc_core::RefCountedPtr<grpc_core::FakeResolverResponseGenerator> - response_generator_; - grpc_core::RefCountedPtr<grpc_core::FakeResolverResponseGenerator> - lb_channel_response_generator_; + std::vector<std::unique_ptr<BackendServerThread>> backends_; + std::vector<std::unique_ptr<BalancerServerThread>> balancers_; + grpc_core::RefCountedPtr<grpc_core::FakeResolverResponseGenerator> + response_generator_; + grpc_core::RefCountedPtr<grpc_core::FakeResolverResponseGenerator> + lb_channel_response_generator_; int xds_resource_does_not_exist_timeout_ms_ = 0; y_absl::InlinedVector<grpc_arg, 2> xds_channel_args_to_add_; grpc_channel_args xds_channel_args_; -}; - -class BasicTest : public XdsEnd2endTest { - public: +}; + +class BasicTest : public XdsEnd2endTest { + public: BasicTest() : XdsEnd2endTest(4, 1) {} -}; - -// Tests that the balancer sends the correct response to the client, and the -// client sends RPCs to the backends using the default child policy. -TEST_P(BasicTest, Vanilla) { - SetNextResolution({}); - SetNextResolutionForLbChannelAllBalancers(); - const size_t kNumRpcsPerAddress = 100; +}; + +// Tests that the balancer sends the correct response to the client, and the +// client sends RPCs to the backends using the default child policy. +TEST_P(BasicTest, Vanilla) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + const size_t kNumRpcsPerAddress = 100; AdsServiceImpl::EdsResourceArgs args({ - {"locality0", GetBackendPorts()}, - }); + {"locality0", GetBackendPorts()}, + }); balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - // Make sure that trying to connect works without a call. - channel_->GetState(true /* try_to_connect */); - // We need to wait for all backends to come online. - WaitForAllBackends(); - // Send kNumRpcsPerAddress RPCs per server. - CheckRpcSendOk(kNumRpcsPerAddress * num_backends_); - // Each backend should have gotten 100 requests. - for (size_t i = 0; i < backends_.size(); ++i) { - EXPECT_EQ(kNumRpcsPerAddress, - backends_[i]->backend_service()->request_count()); - } - // Check LB policy name for the channel. + // Make sure that trying to connect works without a call. + channel_->GetState(true /* try_to_connect */); + // We need to wait for all backends to come online. + WaitForAllBackends(); + // Send kNumRpcsPerAddress RPCs per server. + CheckRpcSendOk(kNumRpcsPerAddress * num_backends_); + // Each backend should have gotten 100 requests. + for (size_t i = 0; i < backends_.size(); ++i) { + EXPECT_EQ(kNumRpcsPerAddress, + backends_[i]->backend_service()->request_count()); + } + // Check LB policy name for the channel. EXPECT_EQ((GetParam().use_xds_resolver() ? "xds_cluster_manager_experimental" : "eds_experimental"), channel_->GetLoadBalancingPolicyName()); -} - -TEST_P(BasicTest, IgnoresUnhealthyEndpoints) { - SetNextResolution({}); - SetNextResolutionForLbChannelAllBalancers(); - const size_t kNumRpcsPerAddress = 100; +} + +TEST_P(BasicTest, IgnoresUnhealthyEndpoints) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + const size_t kNumRpcsPerAddress = 100; AdsServiceImpl::EdsResourceArgs args({ - {"locality0", - GetBackendPorts(), - kDefaultLocalityWeight, - kDefaultLocalityPriority, + {"locality0", + GetBackendPorts(), + kDefaultLocalityWeight, + kDefaultLocalityPriority, {HealthStatus::DRAINING}}, - }); + }); balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - // Make sure that trying to connect works without a call. - channel_->GetState(true /* try_to_connect */); - // We need to wait for all backends to come online. - WaitForAllBackends(/*start_index=*/1); - // Send kNumRpcsPerAddress RPCs per server. - CheckRpcSendOk(kNumRpcsPerAddress * (num_backends_ - 1)); - // Each backend should have gotten 100 requests. - for (size_t i = 1; i < backends_.size(); ++i) { - EXPECT_EQ(kNumRpcsPerAddress, - backends_[i]->backend_service()->request_count()); - } -} - -// Tests that subchannel sharing works when the same backend is listed multiple -// times. -TEST_P(BasicTest, SameBackendListedMultipleTimes) { - SetNextResolution({}); - SetNextResolutionForLbChannelAllBalancers(); - // Same backend listed twice. - std::vector<int> ports(2, backends_[0]->port()); + // Make sure that trying to connect works without a call. + channel_->GetState(true /* try_to_connect */); + // We need to wait for all backends to come online. + WaitForAllBackends(/*start_index=*/1); + // Send kNumRpcsPerAddress RPCs per server. + CheckRpcSendOk(kNumRpcsPerAddress * (num_backends_ - 1)); + // Each backend should have gotten 100 requests. + for (size_t i = 1; i < backends_.size(); ++i) { + EXPECT_EQ(kNumRpcsPerAddress, + backends_[i]->backend_service()->request_count()); + } +} + +// Tests that subchannel sharing works when the same backend is listed multiple +// times. +TEST_P(BasicTest, SameBackendListedMultipleTimes) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + // Same backend listed twice. + std::vector<int> ports(2, backends_[0]->port()); AdsServiceImpl::EdsResourceArgs args({ - {"locality0", ports}, - }); - const size_t kNumRpcsPerAddress = 10; + {"locality0", ports}, + }); + const size_t kNumRpcsPerAddress = 10; balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - // We need to wait for the backend to come online. - WaitForBackend(0); - // Send kNumRpcsPerAddress RPCs per server. - CheckRpcSendOk(kNumRpcsPerAddress * ports.size()); - // Backend should have gotten 20 requests. - EXPECT_EQ(kNumRpcsPerAddress * ports.size(), - backends_[0]->backend_service()->request_count()); - // And they should have come from a single client port, because of - // subchannel sharing. - EXPECT_EQ(1UL, backends_[0]->backend_service()->clients().size()); -} - -// Tests that RPCs will be blocked until a non-empty serverlist is received. -TEST_P(BasicTest, InitiallyEmptyServerlist) { - SetNextResolution({}); - SetNextResolutionForLbChannelAllBalancers(); - const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor(); - const int kCallDeadlineMs = kServerlistDelayMs * 2; - // First response is an empty serverlist, sent right away. + // We need to wait for the backend to come online. + WaitForBackend(0); + // Send kNumRpcsPerAddress RPCs per server. + CheckRpcSendOk(kNumRpcsPerAddress * ports.size()); + // Backend should have gotten 20 requests. + EXPECT_EQ(kNumRpcsPerAddress * ports.size(), + backends_[0]->backend_service()->request_count()); + // And they should have come from a single client port, because of + // subchannel sharing. + EXPECT_EQ(1UL, backends_[0]->backend_service()->clients().size()); +} + +// Tests that RPCs will be blocked until a non-empty serverlist is received. +TEST_P(BasicTest, InitiallyEmptyServerlist) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + const int kServerlistDelayMs = 500 * grpc_test_slowdown_factor(); + const int kCallDeadlineMs = kServerlistDelayMs * 2; + // First response is an empty serverlist, sent right away. AdsServiceImpl::EdsResourceArgs::Locality empty_locality("locality0", {}); AdsServiceImpl::EdsResourceArgs args({ - empty_locality, - }); + empty_locality, + }); balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - // Send non-empty serverlist only after kServerlistDelayMs. + // Send non-empty serverlist only after kServerlistDelayMs. args = AdsServiceImpl::EdsResourceArgs({ - {"locality0", GetBackendPorts()}, - }); + {"locality0", GetBackendPorts()}, + }); std::thread delayed_resource_setter( std::bind(&BasicTest::SetEdsResourceWithDelay, this, 0, AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName()), kServerlistDelayMs)); - const auto t0 = system_clock::now(); - // Client will block: LB will initially send empty serverlist. + const auto t0 = system_clock::now(); + // Client will block: LB will initially send empty serverlist. CheckRpcSendOk( 1, RpcOptions().set_timeout_ms(kCallDeadlineMs).set_wait_for_ready(true)); - const auto ellapsed_ms = - std::chrono::duration_cast<std::chrono::milliseconds>( - system_clock::now() - t0); - // but eventually, the LB sends a serverlist update that allows the call to - // proceed. The call delay must be larger than the delay in sending the - // populated serverlist but under the call's deadline (which is enforced by - // the call's deadline). - EXPECT_GT(ellapsed_ms.count(), kServerlistDelayMs); + const auto ellapsed_ms = + std::chrono::duration_cast<std::chrono::milliseconds>( + system_clock::now() - t0); + // but eventually, the LB sends a serverlist update that allows the call to + // proceed. The call delay must be larger than the delay in sending the + // populated serverlist but under the call's deadline (which is enforced by + // the call's deadline). + EXPECT_GT(ellapsed_ms.count(), kServerlistDelayMs); delayed_resource_setter.join(); -} - -// Tests that RPCs will fail with UNAVAILABLE instead of DEADLINE_EXCEEDED if -// all the servers are unreachable. -TEST_P(BasicTest, AllServersUnreachableFailFast) { - SetNextResolution({}); - SetNextResolutionForLbChannelAllBalancers(); - const size_t kNumUnreachableServers = 5; - std::vector<int> ports; - for (size_t i = 0; i < kNumUnreachableServers; ++i) { - ports.push_back(g_port_saver->GetPort()); - } +} + +// Tests that RPCs will fail with UNAVAILABLE instead of DEADLINE_EXCEEDED if +// all the servers are unreachable. +TEST_P(BasicTest, AllServersUnreachableFailFast) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + const size_t kNumUnreachableServers = 5; + std::vector<int> ports; + for (size_t i = 0; i < kNumUnreachableServers; ++i) { + ports.push_back(g_port_saver->GetPort()); + } AdsServiceImpl::EdsResourceArgs args({ - {"locality0", ports}, - }); + {"locality0", ports}, + }); balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - const Status status = SendRpc(); - // The error shouldn't be DEADLINE_EXCEEDED. - EXPECT_EQ(StatusCode::UNAVAILABLE, status.error_code()); -} - -// Tests that RPCs fail when the backends are down, and will succeed again after -// the backends are restarted. -TEST_P(BasicTest, BackendsRestart) { - SetNextResolution({}); - SetNextResolutionForLbChannelAllBalancers(); + const Status status = SendRpc(); + // The error shouldn't be DEADLINE_EXCEEDED. + EXPECT_EQ(StatusCode::UNAVAILABLE, status.error_code()); +} + +// Tests that RPCs fail when the backends are down, and will succeed again after +// the backends are restarted. +TEST_P(BasicTest, BackendsRestart) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); AdsServiceImpl::EdsResourceArgs args({ - {"locality0", GetBackendPorts()}, - }); + {"locality0", GetBackendPorts()}, + }); balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - WaitForAllBackends(); - // Stop backends. RPCs should fail. - ShutdownAllBackends(); + WaitForAllBackends(); + // Stop backends. RPCs should fail. + ShutdownAllBackends(); // Sending multiple failed requests instead of just one to ensure that the // client notices that all backends are down before we restart them. If we // didn't do this, then a single RPC could fail here due to the race condition @@ -2098,11 +2098,11 @@ TEST_P(BasicTest, BackendsRestart) { // race condition could happen again due to the client not yet having noticed // that the backends were all down. CheckRpcSendFailure(num_backends_); - // Restart all backends. RPCs should start succeeding again. - StartAllBackends(); + // Restart all backends. RPCs should start succeeding again. + StartAllBackends(); CheckRpcSendOk(1, RpcOptions().set_timeout_ms(2000).set_wait_for_ready(true)); -} - +} + TEST_P(BasicTest, IgnoresDuplicateUpdates) { const size_t kNumRpcsPerAddress = 100; SetNextResolution({}); @@ -2559,23 +2559,23 @@ TEST_P(XdsResolverLoadReportingOnlyTest, ChangeClusters) { EXPECT_EQ(1U, balancers_[0]->lrs_service()->response_count()); } -using SecureNamingTest = BasicTest; - -// Tests that secure naming check passes if target name is expected. -TEST_P(SecureNamingTest, TargetNameIsExpected) { - SetNextResolution({}); +using SecureNamingTest = BasicTest; + +// Tests that secure naming check passes if target name is expected. +TEST_P(SecureNamingTest, TargetNameIsExpected) { + SetNextResolution({}); SetNextResolutionForLbChannel({balancers_[0]->port()}, nullptr, "xds_server"); AdsServiceImpl::EdsResourceArgs args({ - {"locality0", GetBackendPorts()}, - }); + {"locality0", GetBackendPorts()}, + }); balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); CheckRpcSendOk(); -} - -// Tests that secure naming check fails if target name is unexpected. -TEST_P(SecureNamingTest, TargetNameIsUnexpected) { - ::testing::FLAGS_gtest_death_test_style = "threadsafe"; +} + +// Tests that secure naming check fails if target name is unexpected. +TEST_P(SecureNamingTest, TargetNameIsUnexpected) { + ::testing::FLAGS_gtest_death_test_style = "threadsafe"; SetNextResolution({}); SetNextResolutionForLbChannel({balancers_[0]->port()}, nullptr, "incorrect_server_name"); @@ -2584,11 +2584,11 @@ TEST_P(SecureNamingTest, TargetNameIsUnexpected) { }); balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - // Make sure that we blow up (via abort() from the security connector) when - // the name from the balancer doesn't match expectations. + // Make sure that we blow up (via abort() from the security connector) when + // the name from the balancer doesn't match expectations. ASSERT_DEATH_IF_SUPPORTED({ CheckRpcSendOk(); }, ""); -} - +} + using LdsTest = BasicTest; // Tests that LDS client should send a NACK if there is no API listener in the @@ -4500,50 +4500,50 @@ TEST_P(TimeoutTest, Eds) { CheckRpcSendFailure(); } -using LocalityMapTest = BasicTest; - -// Tests that the localities in a locality map are picked according to their -// weights. -TEST_P(LocalityMapTest, WeightedRoundRobin) { - SetNextResolution({}); - SetNextResolutionForLbChannelAllBalancers(); - const size_t kNumRpcs = 5000; - const int kLocalityWeight0 = 2; - const int kLocalityWeight1 = 8; - const int kTotalLocalityWeight = kLocalityWeight0 + kLocalityWeight1; - const double kLocalityWeightRate0 = - static_cast<double>(kLocalityWeight0) / kTotalLocalityWeight; - const double kLocalityWeightRate1 = - static_cast<double>(kLocalityWeight1) / kTotalLocalityWeight; - // ADS response contains 2 localities, each of which contains 1 backend. +using LocalityMapTest = BasicTest; + +// Tests that the localities in a locality map are picked according to their +// weights. +TEST_P(LocalityMapTest, WeightedRoundRobin) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + const size_t kNumRpcs = 5000; + const int kLocalityWeight0 = 2; + const int kLocalityWeight1 = 8; + const int kTotalLocalityWeight = kLocalityWeight0 + kLocalityWeight1; + const double kLocalityWeightRate0 = + static_cast<double>(kLocalityWeight0) / kTotalLocalityWeight; + const double kLocalityWeightRate1 = + static_cast<double>(kLocalityWeight1) / kTotalLocalityWeight; + // ADS response contains 2 localities, each of which contains 1 backend. AdsServiceImpl::EdsResourceArgs args({ - {"locality0", GetBackendPorts(0, 1), kLocalityWeight0}, - {"locality1", GetBackendPorts(1, 2), kLocalityWeight1}, - }); + {"locality0", GetBackendPorts(0, 1), kLocalityWeight0}, + {"locality1", GetBackendPorts(1, 2), kLocalityWeight1}, + }); balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - // Wait for both backends to be ready. - WaitForAllBackends(0, 2); - // Send kNumRpcs RPCs. - CheckRpcSendOk(kNumRpcs); - // The locality picking rates should be roughly equal to the expectation. - const double locality_picked_rate_0 = - static_cast<double>(backends_[0]->backend_service()->request_count()) / - kNumRpcs; - const double locality_picked_rate_1 = - static_cast<double>(backends_[1]->backend_service()->request_count()) / - kNumRpcs; - const double kErrorTolerance = 0.2; - EXPECT_THAT(locality_picked_rate_0, - ::testing::AllOf( - ::testing::Ge(kLocalityWeightRate0 * (1 - kErrorTolerance)), - ::testing::Le(kLocalityWeightRate0 * (1 + kErrorTolerance)))); - EXPECT_THAT(locality_picked_rate_1, - ::testing::AllOf( - ::testing::Ge(kLocalityWeightRate1 * (1 - kErrorTolerance)), - ::testing::Le(kLocalityWeightRate1 * (1 + kErrorTolerance)))); -} - + // Wait for both backends to be ready. + WaitForAllBackends(0, 2); + // Send kNumRpcs RPCs. + CheckRpcSendOk(kNumRpcs); + // The locality picking rates should be roughly equal to the expectation. + const double locality_picked_rate_0 = + static_cast<double>(backends_[0]->backend_service()->request_count()) / + kNumRpcs; + const double locality_picked_rate_1 = + static_cast<double>(backends_[1]->backend_service()->request_count()) / + kNumRpcs; + const double kErrorTolerance = 0.2; + EXPECT_THAT(locality_picked_rate_0, + ::testing::AllOf( + ::testing::Ge(kLocalityWeightRate0 * (1 - kErrorTolerance)), + ::testing::Le(kLocalityWeightRate0 * (1 + kErrorTolerance)))); + EXPECT_THAT(locality_picked_rate_1, + ::testing::AllOf( + ::testing::Ge(kLocalityWeightRate1 * (1 - kErrorTolerance)), + ::testing::Le(kLocalityWeightRate1 * (1 + kErrorTolerance)))); +} + // Tests that we correctly handle a locality containing no endpoints. TEST_P(LocalityMapTest, LocalityContainingNoEndpoints) { SetNextResolution({}); @@ -4582,96 +4582,96 @@ TEST_P(LocalityMapTest, NoLocalities) { EXPECT_EQ(status.error_code(), StatusCode::UNAVAILABLE); } -// Tests that the locality map can work properly even when it contains a large -// number of localities. -TEST_P(LocalityMapTest, StressTest) { - SetNextResolution({}); - SetNextResolutionForLbChannelAllBalancers(); - const size_t kNumLocalities = 100; - // The first ADS response contains kNumLocalities localities, each of which - // contains backend 0. +// Tests that the locality map can work properly even when it contains a large +// number of localities. +TEST_P(LocalityMapTest, StressTest) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + const size_t kNumLocalities = 100; + // The first ADS response contains kNumLocalities localities, each of which + // contains backend 0. AdsServiceImpl::EdsResourceArgs args; - for (size_t i = 0; i < kNumLocalities; ++i) { + for (size_t i = 0; i < kNumLocalities; ++i) { TString name = y_absl::StrCat("locality", i); AdsServiceImpl::EdsResourceArgs::Locality locality(name, {backends_[0]->port()}); - args.locality_list.emplace_back(std::move(locality)); - } + args.locality_list.emplace_back(std::move(locality)); + } balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - // The second ADS response contains 1 locality, which contains backend 1. + // The second ADS response contains 1 locality, which contains backend 1. args = AdsServiceImpl::EdsResourceArgs({ - {"locality0", GetBackendPorts(1, 2)}, - }); + {"locality0", GetBackendPorts(1, 2)}, + }); std::thread delayed_resource_setter( std::bind(&BasicTest::SetEdsResourceWithDelay, this, 0, AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName()), 60 * 1000)); - // Wait until backend 0 is ready, before which kNumLocalities localities are - // received and handled by the xds policy. - WaitForBackend(0, /*reset_counters=*/false); - EXPECT_EQ(0U, backends_[1]->backend_service()->request_count()); - // Wait until backend 1 is ready, before which kNumLocalities localities are - // removed by the xds policy. - WaitForBackend(1); + // Wait until backend 0 is ready, before which kNumLocalities localities are + // received and handled by the xds policy. + WaitForBackend(0, /*reset_counters=*/false); + EXPECT_EQ(0U, backends_[1]->backend_service()->request_count()); + // Wait until backend 1 is ready, before which kNumLocalities localities are + // removed by the xds policy. + WaitForBackend(1); delayed_resource_setter.join(); -} - -// Tests that the localities in a locality map are picked correctly after update -// (addition, modification, deletion). -TEST_P(LocalityMapTest, UpdateMap) { - SetNextResolution({}); - SetNextResolutionForLbChannelAllBalancers(); +} + +// Tests that the localities in a locality map are picked correctly after update +// (addition, modification, deletion). +TEST_P(LocalityMapTest, UpdateMap) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); const size_t kNumRpcs = 3000; - // The locality weight for the first 3 localities. - const std::vector<int> kLocalityWeights0 = {2, 3, 4}; - const double kTotalLocalityWeight0 = - std::accumulate(kLocalityWeights0.begin(), kLocalityWeights0.end(), 0); - std::vector<double> locality_weight_rate_0; - for (int weight : kLocalityWeights0) { - locality_weight_rate_0.push_back(weight / kTotalLocalityWeight0); - } - // Delete the first locality, keep the second locality, change the third - // locality's weight from 4 to 2, and add a new locality with weight 6. - const std::vector<int> kLocalityWeights1 = {3, 2, 6}; - const double kTotalLocalityWeight1 = - std::accumulate(kLocalityWeights1.begin(), kLocalityWeights1.end(), 0); - std::vector<double> locality_weight_rate_1 = { - 0 /* placeholder for locality 0 */}; - for (int weight : kLocalityWeights1) { - locality_weight_rate_1.push_back(weight / kTotalLocalityWeight1); - } + // The locality weight for the first 3 localities. + const std::vector<int> kLocalityWeights0 = {2, 3, 4}; + const double kTotalLocalityWeight0 = + std::accumulate(kLocalityWeights0.begin(), kLocalityWeights0.end(), 0); + std::vector<double> locality_weight_rate_0; + for (int weight : kLocalityWeights0) { + locality_weight_rate_0.push_back(weight / kTotalLocalityWeight0); + } + // Delete the first locality, keep the second locality, change the third + // locality's weight from 4 to 2, and add a new locality with weight 6. + const std::vector<int> kLocalityWeights1 = {3, 2, 6}; + const double kTotalLocalityWeight1 = + std::accumulate(kLocalityWeights1.begin(), kLocalityWeights1.end(), 0); + std::vector<double> locality_weight_rate_1 = { + 0 /* placeholder for locality 0 */}; + for (int weight : kLocalityWeights1) { + locality_weight_rate_1.push_back(weight / kTotalLocalityWeight1); + } AdsServiceImpl::EdsResourceArgs args({ - {"locality0", GetBackendPorts(0, 1), 2}, - {"locality1", GetBackendPorts(1, 2), 3}, - {"locality2", GetBackendPorts(2, 3), 4}, - }); + {"locality0", GetBackendPorts(0, 1), 2}, + {"locality1", GetBackendPorts(1, 2), 3}, + {"locality2", GetBackendPorts(2, 3), 4}, + }); balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - // Wait for the first 3 backends to be ready. - WaitForAllBackends(0, 3); - gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); - // Send kNumRpcs RPCs. - CheckRpcSendOk(kNumRpcs); - gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); - // The picking rates of the first 3 backends should be roughly equal to the - // expectation. - std::vector<double> locality_picked_rates; - for (size_t i = 0; i < 3; ++i) { - locality_picked_rates.push_back( - static_cast<double>(backends_[i]->backend_service()->request_count()) / - kNumRpcs); - } - const double kErrorTolerance = 0.2; - for (size_t i = 0; i < 3; ++i) { + // Wait for the first 3 backends to be ready. + WaitForAllBackends(0, 3); + gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + // Send kNumRpcs RPCs. + CheckRpcSendOk(kNumRpcs); + gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + // The picking rates of the first 3 backends should be roughly equal to the + // expectation. + std::vector<double> locality_picked_rates; + for (size_t i = 0; i < 3; ++i) { + locality_picked_rates.push_back( + static_cast<double>(backends_[i]->backend_service()->request_count()) / + kNumRpcs); + } + const double kErrorTolerance = 0.2; + for (size_t i = 0; i < 3; ++i) { gpr_log(GPR_INFO, "Locality %" PRIuPTR " rate %f", i, locality_picked_rates[i]); - EXPECT_THAT( - locality_picked_rates[i], - ::testing::AllOf( - ::testing::Ge(locality_weight_rate_0[i] * (1 - kErrorTolerance)), - ::testing::Le(locality_weight_rate_0[i] * (1 + kErrorTolerance)))); - } + EXPECT_THAT( + locality_picked_rates[i], + ::testing::AllOf( + ::testing::Ge(locality_weight_rate_0[i] * (1 - kErrorTolerance)), + ::testing::Le(locality_weight_rate_0[i] * (1 + kErrorTolerance)))); + } args = AdsServiceImpl::EdsResourceArgs({ {"locality1", GetBackendPorts(1, 2), 3}, {"locality2", GetBackendPorts(2, 3), 2}, @@ -4679,36 +4679,36 @@ TEST_P(LocalityMapTest, UpdateMap) { }); balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - // Backend 3 hasn't received any request. - EXPECT_EQ(0U, backends_[3]->backend_service()->request_count()); - // Wait until the locality update has been processed, as signaled by backend 3 - // receiving a request. + // Backend 3 hasn't received any request. + EXPECT_EQ(0U, backends_[3]->backend_service()->request_count()); + // Wait until the locality update has been processed, as signaled by backend 3 + // receiving a request. WaitForAllBackends(3, 4); - gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); - // Send kNumRpcs RPCs. - CheckRpcSendOk(kNumRpcs); - gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); - // Backend 0 no longer receives any request. - EXPECT_EQ(0U, backends_[0]->backend_service()->request_count()); - // The picking rates of the last 3 backends should be roughly equal to the - // expectation. - locality_picked_rates = {0 /* placeholder for backend 0 */}; - for (size_t i = 1; i < 4; ++i) { - locality_picked_rates.push_back( - static_cast<double>(backends_[i]->backend_service()->request_count()) / - kNumRpcs); - } - for (size_t i = 1; i < 4; ++i) { + gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); + // Send kNumRpcs RPCs. + CheckRpcSendOk(kNumRpcs); + gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); + // Backend 0 no longer receives any request. + EXPECT_EQ(0U, backends_[0]->backend_service()->request_count()); + // The picking rates of the last 3 backends should be roughly equal to the + // expectation. + locality_picked_rates = {0 /* placeholder for backend 0 */}; + for (size_t i = 1; i < 4; ++i) { + locality_picked_rates.push_back( + static_cast<double>(backends_[i]->backend_service()->request_count()) / + kNumRpcs); + } + for (size_t i = 1; i < 4; ++i) { gpr_log(GPR_INFO, "Locality %" PRIuPTR " rate %f", i, locality_picked_rates[i]); - EXPECT_THAT( - locality_picked_rates[i], - ::testing::AllOf( - ::testing::Ge(locality_weight_rate_1[i] * (1 - kErrorTolerance)), - ::testing::Le(locality_weight_rate_1[i] * (1 + kErrorTolerance)))); - } -} - + EXPECT_THAT( + locality_picked_rates[i], + ::testing::AllOf( + ::testing::Ge(locality_weight_rate_1[i] * (1 - kErrorTolerance)), + ::testing::Le(locality_weight_rate_1[i] * (1 + kErrorTolerance)))); + } +} + // Tests that we don't fail RPCs when replacing all of the localities in // a given priority. TEST_P(LocalityMapTest, ReplaceAllLocalitiesInPriority) { @@ -4734,32 +4734,32 @@ TEST_P(LocalityMapTest, ReplaceAllLocalitiesInPriority) { delayed_resource_setter.join(); } -class FailoverTest : public BasicTest { - public: +class FailoverTest : public BasicTest { + public: void SetUp() override { BasicTest::SetUp(); ResetStub(500); } -}; - -// Localities with the highest priority are used when multiple priority exist. -TEST_P(FailoverTest, ChooseHighestPriority) { - SetNextResolution({}); - SetNextResolutionForLbChannelAllBalancers(); +}; + +// Localities with the highest priority are used when multiple priority exist. +TEST_P(FailoverTest, ChooseHighestPriority) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); AdsServiceImpl::EdsResourceArgs args({ - {"locality0", GetBackendPorts(0, 1), kDefaultLocalityWeight, 1}, - {"locality1", GetBackendPorts(1, 2), kDefaultLocalityWeight, 2}, - {"locality2", GetBackendPorts(2, 3), kDefaultLocalityWeight, 3}, - {"locality3", GetBackendPorts(3, 4), kDefaultLocalityWeight, 0}, - }); + {"locality0", GetBackendPorts(0, 1), kDefaultLocalityWeight, 1}, + {"locality1", GetBackendPorts(1, 2), kDefaultLocalityWeight, 2}, + {"locality2", GetBackendPorts(2, 3), kDefaultLocalityWeight, 3}, + {"locality3", GetBackendPorts(3, 4), kDefaultLocalityWeight, 0}, + }); balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - WaitForBackend(3, false); - for (size_t i = 0; i < 3; ++i) { + WaitForBackend(3, false); + for (size_t i = 0; i < 3; ++i) { EXPECT_EQ(0U, backends_[i]->backend_service()->request_count()); - } -} - + } +} + // Does not choose priority with no endpoints. TEST_P(FailoverTest, DoesNotUsePriorityWithNoEndpoints) { SetNextResolution({}); @@ -4794,124 +4794,124 @@ TEST_P(FailoverTest, DoesNotUseLocalityWithNoEndpoints) { EXPECT_EQ(0, std::get<1>(counts)); } -// If the higher priority localities are not reachable, failover to the highest -// priority among the rest. -TEST_P(FailoverTest, Failover) { - SetNextResolution({}); - SetNextResolutionForLbChannelAllBalancers(); +// If the higher priority localities are not reachable, failover to the highest +// priority among the rest. +TEST_P(FailoverTest, Failover) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); AdsServiceImpl::EdsResourceArgs args({ - {"locality0", GetBackendPorts(0, 1), kDefaultLocalityWeight, 1}, - {"locality1", GetBackendPorts(1, 2), kDefaultLocalityWeight, 2}, - {"locality2", GetBackendPorts(2, 3), kDefaultLocalityWeight, 3}, - {"locality3", GetBackendPorts(3, 4), kDefaultLocalityWeight, 0}, - }); - ShutdownBackend(3); - ShutdownBackend(0); + {"locality0", GetBackendPorts(0, 1), kDefaultLocalityWeight, 1}, + {"locality1", GetBackendPorts(1, 2), kDefaultLocalityWeight, 2}, + {"locality2", GetBackendPorts(2, 3), kDefaultLocalityWeight, 3}, + {"locality3", GetBackendPorts(3, 4), kDefaultLocalityWeight, 0}, + }); + ShutdownBackend(3); + ShutdownBackend(0); balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - WaitForBackend(1, false); - for (size_t i = 0; i < 4; ++i) { - if (i == 1) continue; + WaitForBackend(1, false); + for (size_t i = 0; i < 4; ++i) { + if (i == 1) continue; EXPECT_EQ(0U, backends_[i]->backend_service()->request_count()); - } -} - -// If a locality with higher priority than the current one becomes ready, -// switch to it. -TEST_P(FailoverTest, SwitchBackToHigherPriority) { - SetNextResolution({}); - SetNextResolutionForLbChannelAllBalancers(); - const size_t kNumRpcs = 100; + } +} + +// If a locality with higher priority than the current one becomes ready, +// switch to it. +TEST_P(FailoverTest, SwitchBackToHigherPriority) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + const size_t kNumRpcs = 100; AdsServiceImpl::EdsResourceArgs args({ - {"locality0", GetBackendPorts(0, 1), kDefaultLocalityWeight, 1}, - {"locality1", GetBackendPorts(1, 2), kDefaultLocalityWeight, 2}, - {"locality2", GetBackendPorts(2, 3), kDefaultLocalityWeight, 3}, - {"locality3", GetBackendPorts(3, 4), kDefaultLocalityWeight, 0}, - }); - ShutdownBackend(3); - ShutdownBackend(0); + {"locality0", GetBackendPorts(0, 1), kDefaultLocalityWeight, 1}, + {"locality1", GetBackendPorts(1, 2), kDefaultLocalityWeight, 2}, + {"locality2", GetBackendPorts(2, 3), kDefaultLocalityWeight, 3}, + {"locality3", GetBackendPorts(3, 4), kDefaultLocalityWeight, 0}, + }); + ShutdownBackend(3); + ShutdownBackend(0); balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - WaitForBackend(1, false); - for (size_t i = 0; i < 4; ++i) { - if (i == 1) continue; + WaitForBackend(1, false); + for (size_t i = 0; i < 4; ++i) { + if (i == 1) continue; EXPECT_EQ(0U, backends_[i]->backend_service()->request_count()); - } - StartBackend(0); - WaitForBackend(0); - CheckRpcSendOk(kNumRpcs); - EXPECT_EQ(kNumRpcs, backends_[0]->backend_service()->request_count()); -} - -// The first update only contains unavailable priorities. The second update -// contains available priorities. -TEST_P(FailoverTest, UpdateInitialUnavailable) { - SetNextResolution({}); - SetNextResolutionForLbChannelAllBalancers(); + } + StartBackend(0); + WaitForBackend(0); + CheckRpcSendOk(kNumRpcs); + EXPECT_EQ(kNumRpcs, backends_[0]->backend_service()->request_count()); +} + +// The first update only contains unavailable priorities. The second update +// contains available priorities. +TEST_P(FailoverTest, UpdateInitialUnavailable) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); AdsServiceImpl::EdsResourceArgs args({ - {"locality0", GetBackendPorts(0, 1), kDefaultLocalityWeight, 0}, - {"locality1", GetBackendPorts(1, 2), kDefaultLocalityWeight, 1}, - }); + {"locality0", GetBackendPorts(0, 1), kDefaultLocalityWeight, 0}, + {"locality1", GetBackendPorts(1, 2), kDefaultLocalityWeight, 1}, + }); balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); args = AdsServiceImpl::EdsResourceArgs({ - {"locality0", GetBackendPorts(0, 1), kDefaultLocalityWeight, 0}, - {"locality1", GetBackendPorts(1, 2), kDefaultLocalityWeight, 1}, - {"locality2", GetBackendPorts(2, 3), kDefaultLocalityWeight, 2}, - {"locality3", GetBackendPorts(3, 4), kDefaultLocalityWeight, 3}, - }); - ShutdownBackend(0); - ShutdownBackend(1); + {"locality0", GetBackendPorts(0, 1), kDefaultLocalityWeight, 0}, + {"locality1", GetBackendPorts(1, 2), kDefaultLocalityWeight, 1}, + {"locality2", GetBackendPorts(2, 3), kDefaultLocalityWeight, 2}, + {"locality3", GetBackendPorts(3, 4), kDefaultLocalityWeight, 3}, + }); + ShutdownBackend(0); + ShutdownBackend(1); std::thread delayed_resource_setter(std::bind( &BasicTest::SetEdsResourceWithDelay, this, 0, AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName()), 1000)); - gpr_timespec deadline = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_millis(500, GPR_TIMESPAN)); - // Send 0.5 second worth of RPCs. - do { - CheckRpcSendFailure(); - } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); - WaitForBackend(2, false); - for (size_t i = 0; i < 4; ++i) { - if (i == 2) continue; + gpr_timespec deadline = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_millis(500, GPR_TIMESPAN)); + // Send 0.5 second worth of RPCs. + do { + CheckRpcSendFailure(); + } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); + WaitForBackend(2, false); + for (size_t i = 0; i < 4; ++i) { + if (i == 2) continue; EXPECT_EQ(0U, backends_[i]->backend_service()->request_count()); - } + } delayed_resource_setter.join(); -} - -// Tests that after the localities' priorities are updated, we still choose the -// highest READY priority with the updated localities. -TEST_P(FailoverTest, UpdatePriority) { - SetNextResolution({}); - SetNextResolutionForLbChannelAllBalancers(); - const size_t kNumRpcs = 100; +} + +// Tests that after the localities' priorities are updated, we still choose the +// highest READY priority with the updated localities. +TEST_P(FailoverTest, UpdatePriority) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + const size_t kNumRpcs = 100; AdsServiceImpl::EdsResourceArgs args({ - {"locality0", GetBackendPorts(0, 1), kDefaultLocalityWeight, 1}, - {"locality1", GetBackendPorts(1, 2), kDefaultLocalityWeight, 2}, - {"locality2", GetBackendPorts(2, 3), kDefaultLocalityWeight, 3}, - {"locality3", GetBackendPorts(3, 4), kDefaultLocalityWeight, 0}, - }); + {"locality0", GetBackendPorts(0, 1), kDefaultLocalityWeight, 1}, + {"locality1", GetBackendPorts(1, 2), kDefaultLocalityWeight, 2}, + {"locality2", GetBackendPorts(2, 3), kDefaultLocalityWeight, 3}, + {"locality3", GetBackendPorts(3, 4), kDefaultLocalityWeight, 0}, + }); balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); args = AdsServiceImpl::EdsResourceArgs({ - {"locality0", GetBackendPorts(0, 1), kDefaultLocalityWeight, 2}, - {"locality1", GetBackendPorts(1, 2), kDefaultLocalityWeight, 0}, - {"locality2", GetBackendPorts(2, 3), kDefaultLocalityWeight, 1}, - {"locality3", GetBackendPorts(3, 4), kDefaultLocalityWeight, 3}, - }); + {"locality0", GetBackendPorts(0, 1), kDefaultLocalityWeight, 2}, + {"locality1", GetBackendPorts(1, 2), kDefaultLocalityWeight, 0}, + {"locality2", GetBackendPorts(2, 3), kDefaultLocalityWeight, 1}, + {"locality3", GetBackendPorts(3, 4), kDefaultLocalityWeight, 3}, + }); std::thread delayed_resource_setter(std::bind( &BasicTest::SetEdsResourceWithDelay, this, 0, AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName()), 1000)); - WaitForBackend(3, false); - for (size_t i = 0; i < 3; ++i) { + WaitForBackend(3, false); + for (size_t i = 0; i < 3; ++i) { EXPECT_EQ(0U, backends_[i]->backend_service()->request_count()); - } - WaitForBackend(1); - CheckRpcSendOk(kNumRpcs); - EXPECT_EQ(kNumRpcs, backends_[1]->backend_service()->request_count()); + } + WaitForBackend(1); + CheckRpcSendOk(kNumRpcs); + EXPECT_EQ(kNumRpcs, backends_[1]->backend_service()->request_count()); delayed_resource_setter.join(); -} - +} + // Moves all localities in the current priority to a higher priority. TEST_P(FailoverTest, MoveAllLocalitiesInCurrentPriorityToHigherPriority) { SetNextResolution({}); @@ -4951,274 +4951,274 @@ TEST_P(FailoverTest, MoveAllLocalitiesInCurrentPriorityToHigherPriority) { delayed_resource_setter.join(); } -using DropTest = BasicTest; - -// Tests that RPCs are dropped according to the drop config. -TEST_P(DropTest, Vanilla) { - SetNextResolution({}); - SetNextResolutionForLbChannelAllBalancers(); - const size_t kNumRpcs = 5000; - const uint32_t kDropPerMillionForLb = 100000; - const uint32_t kDropPerMillionForThrottle = 200000; - const double kDropRateForLb = kDropPerMillionForLb / 1000000.0; - const double kDropRateForThrottle = kDropPerMillionForThrottle / 1000000.0; - const double KDropRateForLbAndThrottle = - kDropRateForLb + (1 - kDropRateForLb) * kDropRateForThrottle; - // The ADS response contains two drop categories. +using DropTest = BasicTest; + +// Tests that RPCs are dropped according to the drop config. +TEST_P(DropTest, Vanilla) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + const size_t kNumRpcs = 5000; + const uint32_t kDropPerMillionForLb = 100000; + const uint32_t kDropPerMillionForThrottle = 200000; + const double kDropRateForLb = kDropPerMillionForLb / 1000000.0; + const double kDropRateForThrottle = kDropPerMillionForThrottle / 1000000.0; + const double KDropRateForLbAndThrottle = + kDropRateForLb + (1 - kDropRateForLb) * kDropRateForThrottle; + // The ADS response contains two drop categories. AdsServiceImpl::EdsResourceArgs args({ - {"locality0", GetBackendPorts()}, - }); - args.drop_categories = {{kLbDropType, kDropPerMillionForLb}, - {kThrottleDropType, kDropPerMillionForThrottle}}; + {"locality0", GetBackendPorts()}, + }); + args.drop_categories = {{kLbDropType, kDropPerMillionForLb}, + {kThrottleDropType, kDropPerMillionForThrottle}}; balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - WaitForAllBackends(); - // Send kNumRpcs RPCs and count the drops. - size_t num_drops = 0; - for (size_t i = 0; i < kNumRpcs; ++i) { - EchoResponse response; + WaitForAllBackends(); + // Send kNumRpcs RPCs and count the drops. + size_t num_drops = 0; + for (size_t i = 0; i < kNumRpcs; ++i) { + EchoResponse response; const Status status = SendRpc(RpcOptions(), &response); - if (!status.ok() && - status.error_message() == "Call dropped by load balancing policy") { - ++num_drops; - } else { - EXPECT_TRUE(status.ok()) << "code=" << status.error_code() - << " message=" << status.error_message(); + if (!status.ok() && + status.error_message() == "Call dropped by load balancing policy") { + ++num_drops; + } else { + EXPECT_TRUE(status.ok()) << "code=" << status.error_code() + << " message=" << status.error_message(); EXPECT_EQ(response.message(), kRequestMessage); - } - } - // The drop rate should be roughly equal to the expectation. - const double seen_drop_rate = static_cast<double>(num_drops) / kNumRpcs; - const double kErrorTolerance = 0.2; - EXPECT_THAT( - seen_drop_rate, - ::testing::AllOf( - ::testing::Ge(KDropRateForLbAndThrottle * (1 - kErrorTolerance)), - ::testing::Le(KDropRateForLbAndThrottle * (1 + kErrorTolerance)))); -} - -// Tests that drop config is converted correctly from per hundred. -TEST_P(DropTest, DropPerHundred) { - SetNextResolution({}); - SetNextResolutionForLbChannelAllBalancers(); - const size_t kNumRpcs = 5000; - const uint32_t kDropPerHundredForLb = 10; - const double kDropRateForLb = kDropPerHundredForLb / 100.0; - // The ADS response contains one drop category. + } + } + // The drop rate should be roughly equal to the expectation. + const double seen_drop_rate = static_cast<double>(num_drops) / kNumRpcs; + const double kErrorTolerance = 0.2; + EXPECT_THAT( + seen_drop_rate, + ::testing::AllOf( + ::testing::Ge(KDropRateForLbAndThrottle * (1 - kErrorTolerance)), + ::testing::Le(KDropRateForLbAndThrottle * (1 + kErrorTolerance)))); +} + +// Tests that drop config is converted correctly from per hundred. +TEST_P(DropTest, DropPerHundred) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + const size_t kNumRpcs = 5000; + const uint32_t kDropPerHundredForLb = 10; + const double kDropRateForLb = kDropPerHundredForLb / 100.0; + // The ADS response contains one drop category. AdsServiceImpl::EdsResourceArgs args({ - {"locality0", GetBackendPorts()}, - }); - args.drop_categories = {{kLbDropType, kDropPerHundredForLb}}; - args.drop_denominator = FractionalPercent::HUNDRED; + {"locality0", GetBackendPorts()}, + }); + args.drop_categories = {{kLbDropType, kDropPerHundredForLb}}; + args.drop_denominator = FractionalPercent::HUNDRED; balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - WaitForAllBackends(); - // Send kNumRpcs RPCs and count the drops. - size_t num_drops = 0; - for (size_t i = 0; i < kNumRpcs; ++i) { - EchoResponse response; + WaitForAllBackends(); + // Send kNumRpcs RPCs and count the drops. + size_t num_drops = 0; + for (size_t i = 0; i < kNumRpcs; ++i) { + EchoResponse response; const Status status = SendRpc(RpcOptions(), &response); - if (!status.ok() && - status.error_message() == "Call dropped by load balancing policy") { - ++num_drops; - } else { - EXPECT_TRUE(status.ok()) << "code=" << status.error_code() - << " message=" << status.error_message(); + if (!status.ok() && + status.error_message() == "Call dropped by load balancing policy") { + ++num_drops; + } else { + EXPECT_TRUE(status.ok()) << "code=" << status.error_code() + << " message=" << status.error_message(); EXPECT_EQ(response.message(), kRequestMessage); - } - } - // The drop rate should be roughly equal to the expectation. - const double seen_drop_rate = static_cast<double>(num_drops) / kNumRpcs; - const double kErrorTolerance = 0.2; - EXPECT_THAT( - seen_drop_rate, - ::testing::AllOf(::testing::Ge(kDropRateForLb * (1 - kErrorTolerance)), - ::testing::Le(kDropRateForLb * (1 + kErrorTolerance)))); -} - -// Tests that drop config is converted correctly from per ten thousand. -TEST_P(DropTest, DropPerTenThousand) { - SetNextResolution({}); - SetNextResolutionForLbChannelAllBalancers(); - const size_t kNumRpcs = 5000; - const uint32_t kDropPerTenThousandForLb = 1000; - const double kDropRateForLb = kDropPerTenThousandForLb / 10000.0; - // The ADS response contains one drop category. + } + } + // The drop rate should be roughly equal to the expectation. + const double seen_drop_rate = static_cast<double>(num_drops) / kNumRpcs; + const double kErrorTolerance = 0.2; + EXPECT_THAT( + seen_drop_rate, + ::testing::AllOf(::testing::Ge(kDropRateForLb * (1 - kErrorTolerance)), + ::testing::Le(kDropRateForLb * (1 + kErrorTolerance)))); +} + +// Tests that drop config is converted correctly from per ten thousand. +TEST_P(DropTest, DropPerTenThousand) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + const size_t kNumRpcs = 5000; + const uint32_t kDropPerTenThousandForLb = 1000; + const double kDropRateForLb = kDropPerTenThousandForLb / 10000.0; + // The ADS response contains one drop category. AdsServiceImpl::EdsResourceArgs args({ - {"locality0", GetBackendPorts()}, - }); - args.drop_categories = {{kLbDropType, kDropPerTenThousandForLb}}; - args.drop_denominator = FractionalPercent::TEN_THOUSAND; + {"locality0", GetBackendPorts()}, + }); + args.drop_categories = {{kLbDropType, kDropPerTenThousandForLb}}; + args.drop_denominator = FractionalPercent::TEN_THOUSAND; balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - WaitForAllBackends(); - // Send kNumRpcs RPCs and count the drops. - size_t num_drops = 0; - for (size_t i = 0; i < kNumRpcs; ++i) { - EchoResponse response; + WaitForAllBackends(); + // Send kNumRpcs RPCs and count the drops. + size_t num_drops = 0; + for (size_t i = 0; i < kNumRpcs; ++i) { + EchoResponse response; const Status status = SendRpc(RpcOptions(), &response); - if (!status.ok() && - status.error_message() == "Call dropped by load balancing policy") { - ++num_drops; - } else { - EXPECT_TRUE(status.ok()) << "code=" << status.error_code() - << " message=" << status.error_message(); + if (!status.ok() && + status.error_message() == "Call dropped by load balancing policy") { + ++num_drops; + } else { + EXPECT_TRUE(status.ok()) << "code=" << status.error_code() + << " message=" << status.error_message(); EXPECT_EQ(response.message(), kRequestMessage); - } - } - // The drop rate should be roughly equal to the expectation. - const double seen_drop_rate = static_cast<double>(num_drops) / kNumRpcs; - const double kErrorTolerance = 0.2; - EXPECT_THAT( - seen_drop_rate, - ::testing::AllOf(::testing::Ge(kDropRateForLb * (1 - kErrorTolerance)), - ::testing::Le(kDropRateForLb * (1 + kErrorTolerance)))); -} - -// Tests that drop is working correctly after update. -TEST_P(DropTest, Update) { - SetNextResolution({}); - SetNextResolutionForLbChannelAllBalancers(); + } + } + // The drop rate should be roughly equal to the expectation. + const double seen_drop_rate = static_cast<double>(num_drops) / kNumRpcs; + const double kErrorTolerance = 0.2; + EXPECT_THAT( + seen_drop_rate, + ::testing::AllOf(::testing::Ge(kDropRateForLb * (1 - kErrorTolerance)), + ::testing::Le(kDropRateForLb * (1 + kErrorTolerance)))); +} + +// Tests that drop is working correctly after update. +TEST_P(DropTest, Update) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); const size_t kNumRpcs = 3000; - const uint32_t kDropPerMillionForLb = 100000; - const uint32_t kDropPerMillionForThrottle = 200000; - const double kDropRateForLb = kDropPerMillionForLb / 1000000.0; - const double kDropRateForThrottle = kDropPerMillionForThrottle / 1000000.0; - const double KDropRateForLbAndThrottle = - kDropRateForLb + (1 - kDropRateForLb) * kDropRateForThrottle; - // The first ADS response contains one drop category. + const uint32_t kDropPerMillionForLb = 100000; + const uint32_t kDropPerMillionForThrottle = 200000; + const double kDropRateForLb = kDropPerMillionForLb / 1000000.0; + const double kDropRateForThrottle = kDropPerMillionForThrottle / 1000000.0; + const double KDropRateForLbAndThrottle = + kDropRateForLb + (1 - kDropRateForLb) * kDropRateForThrottle; + // The first ADS response contains one drop category. AdsServiceImpl::EdsResourceArgs args({ - {"locality0", GetBackendPorts()}, - }); - args.drop_categories = {{kLbDropType, kDropPerMillionForLb}}; + {"locality0", GetBackendPorts()}, + }); + args.drop_categories = {{kLbDropType, kDropPerMillionForLb}}; balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - WaitForAllBackends(); - // Send kNumRpcs RPCs and count the drops. - size_t num_drops = 0; - gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); - for (size_t i = 0; i < kNumRpcs; ++i) { - EchoResponse response; + WaitForAllBackends(); + // Send kNumRpcs RPCs and count the drops. + size_t num_drops = 0; + gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + for (size_t i = 0; i < kNumRpcs; ++i) { + EchoResponse response; const Status status = SendRpc(RpcOptions(), &response); - if (!status.ok() && - status.error_message() == "Call dropped by load balancing policy") { - ++num_drops; - } else { - EXPECT_TRUE(status.ok()) << "code=" << status.error_code() - << " message=" << status.error_message(); + if (!status.ok() && + status.error_message() == "Call dropped by load balancing policy") { + ++num_drops; + } else { + EXPECT_TRUE(status.ok()) << "code=" << status.error_code() + << " message=" << status.error_message(); EXPECT_EQ(response.message(), kRequestMessage); - } - } - gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); - // The drop rate should be roughly equal to the expectation. - double seen_drop_rate = static_cast<double>(num_drops) / kNumRpcs; + } + } + gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + // The drop rate should be roughly equal to the expectation. + double seen_drop_rate = static_cast<double>(num_drops) / kNumRpcs; gpr_log(GPR_INFO, "First batch drop rate %f", seen_drop_rate); - const double kErrorTolerance = 0.3; - EXPECT_THAT( - seen_drop_rate, - ::testing::AllOf(::testing::Ge(kDropRateForLb * (1 - kErrorTolerance)), - ::testing::Le(kDropRateForLb * (1 + kErrorTolerance)))); + const double kErrorTolerance = 0.3; + EXPECT_THAT( + seen_drop_rate, + ::testing::AllOf(::testing::Ge(kDropRateForLb * (1 - kErrorTolerance)), + ::testing::Le(kDropRateForLb * (1 + kErrorTolerance)))); // The second ADS response contains two drop categories, send an update EDS // response. args.drop_categories = {{kLbDropType, kDropPerMillionForLb}, {kThrottleDropType, kDropPerMillionForThrottle}}; balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - // Wait until the drop rate increases to the middle of the two configs, which - // implies that the update has been in effect. - const double kDropRateThreshold = - (kDropRateForLb + KDropRateForLbAndThrottle) / 2; - size_t num_rpcs = kNumRpcs; - while (seen_drop_rate < kDropRateThreshold) { - EchoResponse response; + // Wait until the drop rate increases to the middle of the two configs, which + // implies that the update has been in effect. + const double kDropRateThreshold = + (kDropRateForLb + KDropRateForLbAndThrottle) / 2; + size_t num_rpcs = kNumRpcs; + while (seen_drop_rate < kDropRateThreshold) { + EchoResponse response; const Status status = SendRpc(RpcOptions(), &response); - ++num_rpcs; - if (!status.ok() && - status.error_message() == "Call dropped by load balancing policy") { - ++num_drops; - } else { - EXPECT_TRUE(status.ok()) << "code=" << status.error_code() - << " message=" << status.error_message(); + ++num_rpcs; + if (!status.ok() && + status.error_message() == "Call dropped by load balancing policy") { + ++num_drops; + } else { + EXPECT_TRUE(status.ok()) << "code=" << status.error_code() + << " message=" << status.error_message(); EXPECT_EQ(response.message(), kRequestMessage); - } - seen_drop_rate = static_cast<double>(num_drops) / num_rpcs; - } - // Send kNumRpcs RPCs and count the drops. - num_drops = 0; - gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); - for (size_t i = 0; i < kNumRpcs; ++i) { - EchoResponse response; + } + seen_drop_rate = static_cast<double>(num_drops) / num_rpcs; + } + // Send kNumRpcs RPCs and count the drops. + num_drops = 0; + gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); + for (size_t i = 0; i < kNumRpcs; ++i) { + EchoResponse response; const Status status = SendRpc(RpcOptions(), &response); - if (!status.ok() && - status.error_message() == "Call dropped by load balancing policy") { - ++num_drops; - } else { - EXPECT_TRUE(status.ok()) << "code=" << status.error_code() - << " message=" << status.error_message(); + if (!status.ok() && + status.error_message() == "Call dropped by load balancing policy") { + ++num_drops; + } else { + EXPECT_TRUE(status.ok()) << "code=" << status.error_code() + << " message=" << status.error_message(); EXPECT_EQ(response.message(), kRequestMessage); - } - } - gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); - // The new drop rate should be roughly equal to the expectation. - seen_drop_rate = static_cast<double>(num_drops) / kNumRpcs; + } + } + gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); + // The new drop rate should be roughly equal to the expectation. + seen_drop_rate = static_cast<double>(num_drops) / kNumRpcs; gpr_log(GPR_INFO, "Second batch drop rate %f", seen_drop_rate); - EXPECT_THAT( - seen_drop_rate, - ::testing::AllOf( - ::testing::Ge(KDropRateForLbAndThrottle * (1 - kErrorTolerance)), - ::testing::Le(KDropRateForLbAndThrottle * (1 + kErrorTolerance)))); -} - -// Tests that all the RPCs are dropped if any drop category drops 100%. -TEST_P(DropTest, DropAll) { - SetNextResolution({}); - SetNextResolutionForLbChannelAllBalancers(); - const size_t kNumRpcs = 1000; - const uint32_t kDropPerMillionForLb = 100000; - const uint32_t kDropPerMillionForThrottle = 1000000; - // The ADS response contains two drop categories. + EXPECT_THAT( + seen_drop_rate, + ::testing::AllOf( + ::testing::Ge(KDropRateForLbAndThrottle * (1 - kErrorTolerance)), + ::testing::Le(KDropRateForLbAndThrottle * (1 + kErrorTolerance)))); +} + +// Tests that all the RPCs are dropped if any drop category drops 100%. +TEST_P(DropTest, DropAll) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + const size_t kNumRpcs = 1000; + const uint32_t kDropPerMillionForLb = 100000; + const uint32_t kDropPerMillionForThrottle = 1000000; + // The ADS response contains two drop categories. AdsServiceImpl::EdsResourceArgs args; - args.drop_categories = {{kLbDropType, kDropPerMillionForLb}, - {kThrottleDropType, kDropPerMillionForThrottle}}; + args.drop_categories = {{kLbDropType, kDropPerMillionForLb}, + {kThrottleDropType, kDropPerMillionForThrottle}}; balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - // Send kNumRpcs RPCs and all of them are dropped. - for (size_t i = 0; i < kNumRpcs; ++i) { - EchoResponse response; + // Send kNumRpcs RPCs and all of them are dropped. + for (size_t i = 0; i < kNumRpcs; ++i) { + EchoResponse response; const Status status = SendRpc(RpcOptions(), &response); EXPECT_EQ(status.error_code(), StatusCode::UNAVAILABLE); EXPECT_EQ(status.error_message(), "Call dropped by load balancing policy"); - } -} - -class BalancerUpdateTest : public XdsEnd2endTest { - public: + } +} + +class BalancerUpdateTest : public XdsEnd2endTest { + public: BalancerUpdateTest() : XdsEnd2endTest(4, 3) {} -}; - -// Tests that the old LB call is still used after the balancer address update as -// long as that call is still alive. -TEST_P(BalancerUpdateTest, UpdateBalancersButKeepUsingOriginalBalancer) { - SetNextResolution({}); - SetNextResolutionForLbChannelAllBalancers(); +}; + +// Tests that the old LB call is still used after the balancer address update as +// long as that call is still alive. +TEST_P(BalancerUpdateTest, UpdateBalancersButKeepUsingOriginalBalancer) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); AdsServiceImpl::EdsResourceArgs args({ - {"locality0", {backends_[0]->port()}}, - }); + {"locality0", {backends_[0]->port()}}, + }); balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); args = AdsServiceImpl::EdsResourceArgs({ - {"locality0", {backends_[1]->port()}}, - }); + {"locality0", {backends_[1]->port()}}, + }); balancers_[1]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - // Wait until the first backend is ready. - WaitForBackend(0); - // Send 10 requests. - gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); - CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); - // All 10 requests should have gone to the first backend. - EXPECT_EQ(10U, backends_[0]->backend_service()->request_count()); + // Wait until the first backend is ready. + WaitForBackend(0); + // Send 10 requests. + gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + CheckRpcSendOk(10); + gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + // All 10 requests should have gone to the first backend. + EXPECT_EQ(10U, backends_[0]->backend_service()->request_count()); // The ADS service of balancer 0 sent at least 1 response. EXPECT_GT(balancers_[0]->ads_service()->eds_response_state().state, AdsServiceImpl::ResponseState::NOT_SENT); @@ -5230,19 +5230,19 @@ TEST_P(BalancerUpdateTest, UpdateBalancersButKeepUsingOriginalBalancer) { AdsServiceImpl::ResponseState::NOT_SENT) << "Error Message:" << balancers_[2]->ads_service()->eds_response_state().error_message; - gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); - SetNextResolutionForLbChannel({balancers_[1]->port()}); - gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); - EXPECT_EQ(0U, backends_[1]->backend_service()->request_count()); - gpr_timespec deadline = gpr_time_add( - gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(10000, GPR_TIMESPAN)); - // Send 10 seconds worth of RPCs - do { - CheckRpcSendOk(); - } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); - // The current LB call is still working, so xds continued using it to the - // first balancer, which doesn't assign the second backend. - EXPECT_EQ(0U, backends_[1]->backend_service()->request_count()); + gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); + SetNextResolutionForLbChannel({balancers_[1]->port()}); + gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); + EXPECT_EQ(0U, backends_[1]->backend_service()->request_count()); + gpr_timespec deadline = gpr_time_add( + gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(10000, GPR_TIMESPAN)); + // Send 10 seconds worth of RPCs + do { + CheckRpcSendOk(); + } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); + // The current LB call is still working, so xds continued using it to the + // first balancer, which doesn't assign the second backend. + EXPECT_EQ(0U, backends_[1]->backend_service()->request_count()); // The ADS service of balancer 0 sent at least 1 response. EXPECT_GT(balancers_[0]->ads_service()->eds_response_state().state, AdsServiceImpl::ResponseState::NOT_SENT); @@ -5254,34 +5254,34 @@ TEST_P(BalancerUpdateTest, UpdateBalancersButKeepUsingOriginalBalancer) { AdsServiceImpl::ResponseState::NOT_SENT) << "Error Message:" << balancers_[2]->ads_service()->eds_response_state().error_message; -} - -// Tests that the old LB call is still used after multiple balancer address -// updates as long as that call is still alive. Send an update with the same set -// of LBs as the one in SetUp() in order to verify that the LB channel inside -// xds keeps the initial connection (which by definition is also present in the -// update). -TEST_P(BalancerUpdateTest, Repeated) { - SetNextResolution({}); - SetNextResolutionForLbChannelAllBalancers(); +} + +// Tests that the old LB call is still used after multiple balancer address +// updates as long as that call is still alive. Send an update with the same set +// of LBs as the one in SetUp() in order to verify that the LB channel inside +// xds keeps the initial connection (which by definition is also present in the +// update). +TEST_P(BalancerUpdateTest, Repeated) { + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); AdsServiceImpl::EdsResourceArgs args({ - {"locality0", {backends_[0]->port()}}, - }); + {"locality0", {backends_[0]->port()}}, + }); balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); args = AdsServiceImpl::EdsResourceArgs({ - {"locality0", {backends_[1]->port()}}, - }); + {"locality0", {backends_[1]->port()}}, + }); balancers_[1]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - // Wait until the first backend is ready. - WaitForBackend(0); - // Send 10 requests. - gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); - CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); - // All 10 requests should have gone to the first backend. - EXPECT_EQ(10U, backends_[0]->backend_service()->request_count()); + // Wait until the first backend is ready. + WaitForBackend(0); + // Send 10 requests. + gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + CheckRpcSendOk(10); + gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + // All 10 requests should have gone to the first backend. + EXPECT_EQ(10U, backends_[0]->backend_service()->request_count()); // The ADS service of balancer 0 sent at least 1 response. EXPECT_GT(balancers_[0]->ads_service()->eds_response_state().state, AdsServiceImpl::ResponseState::NOT_SENT); @@ -5293,63 +5293,63 @@ TEST_P(BalancerUpdateTest, Repeated) { AdsServiceImpl::ResponseState::NOT_SENT) << "Error Message:" << balancers_[2]->ads_service()->eds_response_state().error_message; - std::vector<int> ports; - ports.emplace_back(balancers_[0]->port()); - ports.emplace_back(balancers_[1]->port()); - ports.emplace_back(balancers_[2]->port()); - gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); - SetNextResolutionForLbChannel(ports); - gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); - EXPECT_EQ(0U, backends_[1]->backend_service()->request_count()); - gpr_timespec deadline = gpr_time_add( - gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(10000, GPR_TIMESPAN)); - // Send 10 seconds worth of RPCs - do { - CheckRpcSendOk(); - } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); - // xds continued using the original LB call to the first balancer, which - // doesn't assign the second backend. - EXPECT_EQ(0U, backends_[1]->backend_service()->request_count()); - ports.clear(); - ports.emplace_back(balancers_[0]->port()); - ports.emplace_back(balancers_[1]->port()); - gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 2 =========="); - SetNextResolutionForLbChannel(ports); - gpr_log(GPR_INFO, "========= UPDATE 2 DONE =========="); - EXPECT_EQ(0U, backends_[1]->backend_service()->request_count()); - deadline = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), - gpr_time_from_millis(10000, GPR_TIMESPAN)); - // Send 10 seconds worth of RPCs - do { - CheckRpcSendOk(); - } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); - // xds continued using the original LB call to the first balancer, which - // doesn't assign the second backend. - EXPECT_EQ(0U, backends_[1]->backend_service()->request_count()); -} - -// Tests that if the balancer is down, the RPCs will still be sent to the -// backends according to the last balancer response, until a new balancer is -// reachable. -TEST_P(BalancerUpdateTest, DeadUpdate) { - SetNextResolution({}); - SetNextResolutionForLbChannel({balancers_[0]->port()}); + std::vector<int> ports; + ports.emplace_back(balancers_[0]->port()); + ports.emplace_back(balancers_[1]->port()); + ports.emplace_back(balancers_[2]->port()); + gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); + SetNextResolutionForLbChannel(ports); + gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); + EXPECT_EQ(0U, backends_[1]->backend_service()->request_count()); + gpr_timespec deadline = gpr_time_add( + gpr_now(GPR_CLOCK_REALTIME), gpr_time_from_millis(10000, GPR_TIMESPAN)); + // Send 10 seconds worth of RPCs + do { + CheckRpcSendOk(); + } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); + // xds continued using the original LB call to the first balancer, which + // doesn't assign the second backend. + EXPECT_EQ(0U, backends_[1]->backend_service()->request_count()); + ports.clear(); + ports.emplace_back(balancers_[0]->port()); + ports.emplace_back(balancers_[1]->port()); + gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 2 =========="); + SetNextResolutionForLbChannel(ports); + gpr_log(GPR_INFO, "========= UPDATE 2 DONE =========="); + EXPECT_EQ(0U, backends_[1]->backend_service()->request_count()); + deadline = gpr_time_add(gpr_now(GPR_CLOCK_REALTIME), + gpr_time_from_millis(10000, GPR_TIMESPAN)); + // Send 10 seconds worth of RPCs + do { + CheckRpcSendOk(); + } while (gpr_time_cmp(gpr_now(GPR_CLOCK_REALTIME), deadline) < 0); + // xds continued using the original LB call to the first balancer, which + // doesn't assign the second backend. + EXPECT_EQ(0U, backends_[1]->backend_service()->request_count()); +} + +// Tests that if the balancer is down, the RPCs will still be sent to the +// backends according to the last balancer response, until a new balancer is +// reachable. +TEST_P(BalancerUpdateTest, DeadUpdate) { + SetNextResolution({}); + SetNextResolutionForLbChannel({balancers_[0]->port()}); AdsServiceImpl::EdsResourceArgs args({ - {"locality0", {backends_[0]->port()}}, - }); + {"locality0", {backends_[0]->port()}}, + }); balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); args = AdsServiceImpl::EdsResourceArgs({ - {"locality0", {backends_[1]->port()}}, - }); + {"locality0", {backends_[1]->port()}}, + }); balancers_[1]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - // Start servers and send 10 RPCs per server. - gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); - CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); - // All 10 requests should have gone to the first backend. - EXPECT_EQ(10U, backends_[0]->backend_service()->request_count()); + // Start servers and send 10 RPCs per server. + gpr_log(GPR_INFO, "========= BEFORE FIRST BATCH =========="); + CheckRpcSendOk(10); + gpr_log(GPR_INFO, "========= DONE WITH FIRST BATCH =========="); + // All 10 requests should have gone to the first backend. + EXPECT_EQ(10U, backends_[0]->backend_service()->request_count()); // The ADS service of balancer 0 sent at least 1 response. EXPECT_GT(balancers_[0]->ads_service()->eds_response_state().state, AdsServiceImpl::ResponseState::NOT_SENT); @@ -5361,17 +5361,17 @@ TEST_P(BalancerUpdateTest, DeadUpdate) { AdsServiceImpl::ResponseState::NOT_SENT) << "Error Message:" << balancers_[2]->ads_service()->eds_response_state().error_message; - // Kill balancer 0 - gpr_log(GPR_INFO, "********** ABOUT TO KILL BALANCER 0 *************"); - balancers_[0]->Shutdown(); - gpr_log(GPR_INFO, "********** KILLED BALANCER 0 *************"); - // This is serviced by the existing child policy. - gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); - CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); - // All 10 requests should again have gone to the first backend. - EXPECT_EQ(20U, backends_[0]->backend_service()->request_count()); - EXPECT_EQ(0U, backends_[1]->backend_service()->request_count()); + // Kill balancer 0 + gpr_log(GPR_INFO, "********** ABOUT TO KILL BALANCER 0 *************"); + balancers_[0]->Shutdown(); + gpr_log(GPR_INFO, "********** KILLED BALANCER 0 *************"); + // This is serviced by the existing child policy. + gpr_log(GPR_INFO, "========= BEFORE SECOND BATCH =========="); + CheckRpcSendOk(10); + gpr_log(GPR_INFO, "========= DONE WITH SECOND BATCH =========="); + // All 10 requests should again have gone to the first backend. + EXPECT_EQ(20U, backends_[0]->backend_service()->request_count()); + EXPECT_EQ(0U, backends_[1]->backend_service()->request_count()); // The ADS service of no balancers sent anything EXPECT_EQ(balancers_[0]->ads_service()->eds_response_state().state, AdsServiceImpl::ResponseState::NOT_SENT) @@ -5385,21 +5385,21 @@ TEST_P(BalancerUpdateTest, DeadUpdate) { AdsServiceImpl::ResponseState::NOT_SENT) << "Error Message:" << balancers_[2]->ads_service()->eds_response_state().error_message; - gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); - SetNextResolutionForLbChannel({balancers_[1]->port()}); - gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); - // Wait until update has been processed, as signaled by the second backend - // receiving a request. In the meantime, the client continues to be serviced - // (by the first backend) without interruption. - EXPECT_EQ(0U, backends_[1]->backend_service()->request_count()); - WaitForBackend(1); - // This is serviced by the updated RR policy - backends_[1]->backend_service()->ResetCounters(); - gpr_log(GPR_INFO, "========= BEFORE THIRD BATCH =========="); - CheckRpcSendOk(10); - gpr_log(GPR_INFO, "========= DONE WITH THIRD BATCH =========="); - // All 10 requests should have gone to the second backend. - EXPECT_EQ(10U, backends_[1]->backend_service()->request_count()); + gpr_log(GPR_INFO, "========= ABOUT TO UPDATE 1 =========="); + SetNextResolutionForLbChannel({balancers_[1]->port()}); + gpr_log(GPR_INFO, "========= UPDATE 1 DONE =========="); + // Wait until update has been processed, as signaled by the second backend + // receiving a request. In the meantime, the client continues to be serviced + // (by the first backend) without interruption. + EXPECT_EQ(0U, backends_[1]->backend_service()->request_count()); + WaitForBackend(1); + // This is serviced by the updated RR policy + backends_[1]->backend_service()->ResetCounters(); + gpr_log(GPR_INFO, "========= BEFORE THIRD BATCH =========="); + CheckRpcSendOk(10); + gpr_log(GPR_INFO, "========= DONE WITH THIRD BATCH =========="); + // All 10 requests should have gone to the second backend. + EXPECT_EQ(10U, backends_[1]->backend_service()->request_count()); // The ADS service of balancer 1 sent at least 1 response. EXPECT_EQ(balancers_[0]->ads_service()->eds_response_state().state, AdsServiceImpl::ResponseState::NOT_SENT) @@ -5411,44 +5411,44 @@ TEST_P(BalancerUpdateTest, DeadUpdate) { AdsServiceImpl::ResponseState::NOT_SENT) << "Error Message:" << balancers_[2]->ads_service()->eds_response_state().error_message; -} - -// The re-resolution tests are deferred because they rely on the fallback mode, -// which hasn't been supported. - -// TODO(juanlishen): Add TEST_P(BalancerUpdateTest, ReresolveDeadBackend). - -// TODO(juanlishen): Add TEST_P(UpdatesWithClientLoadReportingTest, -// ReresolveDeadBalancer) - -class ClientLoadReportingTest : public XdsEnd2endTest { - public: - ClientLoadReportingTest() : XdsEnd2endTest(4, 1, 3) {} -}; - -// Tests that the load report received at the balancer is correct. -TEST_P(ClientLoadReportingTest, Vanilla) { +} + +// The re-resolution tests are deferred because they rely on the fallback mode, +// which hasn't been supported. + +// TODO(juanlishen): Add TEST_P(BalancerUpdateTest, ReresolveDeadBackend). + +// TODO(juanlishen): Add TEST_P(UpdatesWithClientLoadReportingTest, +// ReresolveDeadBalancer) + +class ClientLoadReportingTest : public XdsEnd2endTest { + public: + ClientLoadReportingTest() : XdsEnd2endTest(4, 1, 3) {} +}; + +// Tests that the load report received at the balancer is correct. +TEST_P(ClientLoadReportingTest, Vanilla) { if (!GetParam().use_xds_resolver()) { balancers_[0]->lrs_service()->set_cluster_names({kServerName}); } - SetNextResolution({}); - SetNextResolutionForLbChannel({balancers_[0]->port()}); + SetNextResolution({}); + SetNextResolutionForLbChannel({balancers_[0]->port()}); const size_t kNumRpcsPerAddress = 10; const size_t kNumFailuresPerAddress = 3; - // TODO(juanlishen): Partition the backends after multiple localities is - // tested. + // TODO(juanlishen): Partition the backends after multiple localities is + // tested. AdsServiceImpl::EdsResourceArgs args({ - {"locality0", GetBackendPorts()}, - }); + {"locality0", GetBackendPorts()}, + }); balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - // Wait until all backends are ready. - int num_ok = 0; - int num_failure = 0; - int num_drops = 0; - std::tie(num_ok, num_failure, num_drops) = WaitForAllBackends(); - // Send kNumRpcsPerAddress RPCs per server. - CheckRpcSendOk(kNumRpcsPerAddress * num_backends_); + // Wait until all backends are ready. + int num_ok = 0; + int num_failure = 0; + int num_drops = 0; + std::tie(num_ok, num_failure, num_drops) = WaitForAllBackends(); + // Send kNumRpcsPerAddress RPCs per server. + CheckRpcSendOk(kNumRpcsPerAddress * num_backends_); CheckRpcSendFailure(kNumFailuresPerAddress * num_backends_, RpcOptions().set_server_fail(true)); // Check that each backend got the right number of requests. @@ -5541,83 +5541,83 @@ TEST_P(ClientLoadReportingTest, HonorsClustersRequestedByLrsServer) { std::tie(num_ok, num_failure, num_drops) = WaitForAllBackends(); // Send kNumRpcsPerAddress RPCs per server. CheckRpcSendOk(kNumRpcsPerAddress * num_backends_); - // Each backend should have gotten 100 requests. - for (size_t i = 0; i < backends_.size(); ++i) { - EXPECT_EQ(kNumRpcsPerAddress, - backends_[i]->backend_service()->request_count()); - } - // The LRS service got a single request, and sent a single response. - EXPECT_EQ(1U, balancers_[0]->lrs_service()->request_count()); - EXPECT_EQ(1U, balancers_[0]->lrs_service()->response_count()); - // The load report received at the balancer should be correct. + // Each backend should have gotten 100 requests. + for (size_t i = 0; i < backends_.size(); ++i) { + EXPECT_EQ(kNumRpcsPerAddress, + backends_[i]->backend_service()->request_count()); + } + // The LRS service got a single request, and sent a single response. + EXPECT_EQ(1U, balancers_[0]->lrs_service()->request_count()); + EXPECT_EQ(1U, balancers_[0]->lrs_service()->response_count()); + // The load report received at the balancer should be correct. std::vector<ClientStats> load_report = balancers_[0]->lrs_service()->WaitForLoadReport(); ASSERT_EQ(load_report.size(), 0UL); -} - -// Tests that if the balancer restarts, the client load report contains the -// stats before and after the restart correctly. -TEST_P(ClientLoadReportingTest, BalancerRestart) { +} + +// Tests that if the balancer restarts, the client load report contains the +// stats before and after the restart correctly. +TEST_P(ClientLoadReportingTest, BalancerRestart) { if (!GetParam().use_xds_resolver()) { balancers_[0]->lrs_service()->set_cluster_names({kServerName}); } - SetNextResolution({}); - SetNextResolutionForLbChannel({balancers_[0]->port()}); - const size_t kNumBackendsFirstPass = backends_.size() / 2; - const size_t kNumBackendsSecondPass = - backends_.size() - kNumBackendsFirstPass; + SetNextResolution({}); + SetNextResolutionForLbChannel({balancers_[0]->port()}); + const size_t kNumBackendsFirstPass = backends_.size() / 2; + const size_t kNumBackendsSecondPass = + backends_.size() - kNumBackendsFirstPass; AdsServiceImpl::EdsResourceArgs args({ - {"locality0", GetBackendPorts(0, kNumBackendsFirstPass)}, - }); + {"locality0", GetBackendPorts(0, kNumBackendsFirstPass)}, + }); balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - // Wait until all backends returned by the balancer are ready. - int num_ok = 0; - int num_failure = 0; - int num_drops = 0; - std::tie(num_ok, num_failure, num_drops) = - WaitForAllBackends(/* start_index */ 0, - /* stop_index */ kNumBackendsFirstPass); + // Wait until all backends returned by the balancer are ready. + int num_ok = 0; + int num_failure = 0; + int num_drops = 0; + std::tie(num_ok, num_failure, num_drops) = + WaitForAllBackends(/* start_index */ 0, + /* stop_index */ kNumBackendsFirstPass); std::vector<ClientStats> load_report = balancers_[0]->lrs_service()->WaitForLoadReport(); ASSERT_EQ(load_report.size(), 1UL); ClientStats client_stats = std::move(load_report.front()); - EXPECT_EQ(static_cast<size_t>(num_ok), + EXPECT_EQ(static_cast<size_t>(num_ok), client_stats.total_successful_requests()); EXPECT_EQ(0U, client_stats.total_requests_in_progress()); EXPECT_EQ(0U, client_stats.total_error_requests()); EXPECT_EQ(0U, client_stats.total_dropped_requests()); - // Shut down the balancer. - balancers_[0]->Shutdown(); - // We should continue using the last EDS response we received from the - // balancer before it was shut down. - // Note: We need to use WaitForAllBackends() here instead of just - // CheckRpcSendOk(kNumBackendsFirstPass), because when the balancer - // shuts down, the XdsClient will generate an error to the - // ServiceConfigWatcher, which will cause the xds resolver to send a - // no-op update to the LB policy. When this update gets down to the - // round_robin child policy for the locality, it will generate a new - // subchannel list, which resets the start index randomly. So we need - // to be a little more permissive here to avoid spurious failures. - ResetBackendCounters(); - int num_started = std::get<0>(WaitForAllBackends( - /* start_index */ 0, /* stop_index */ kNumBackendsFirstPass)); - // Now restart the balancer, this time pointing to the new backends. + // Shut down the balancer. + balancers_[0]->Shutdown(); + // We should continue using the last EDS response we received from the + // balancer before it was shut down. + // Note: We need to use WaitForAllBackends() here instead of just + // CheckRpcSendOk(kNumBackendsFirstPass), because when the balancer + // shuts down, the XdsClient will generate an error to the + // ServiceConfigWatcher, which will cause the xds resolver to send a + // no-op update to the LB policy. When this update gets down to the + // round_robin child policy for the locality, it will generate a new + // subchannel list, which resets the start index randomly. So we need + // to be a little more permissive here to avoid spurious failures. + ResetBackendCounters(); + int num_started = std::get<0>(WaitForAllBackends( + /* start_index */ 0, /* stop_index */ kNumBackendsFirstPass)); + // Now restart the balancer, this time pointing to the new backends. balancers_[0]->Start(); args = AdsServiceImpl::EdsResourceArgs({ - {"locality0", GetBackendPorts(kNumBackendsFirstPass)}, - }); + {"locality0", GetBackendPorts(kNumBackendsFirstPass)}, + }); balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - // Wait for queries to start going to one of the new backends. - // This tells us that we're now using the new serverlist. - std::tie(num_ok, num_failure, num_drops) = - WaitForAllBackends(/* start_index */ kNumBackendsFirstPass); - num_started += num_ok + num_failure + num_drops; - // Send one RPC per backend. - CheckRpcSendOk(kNumBackendsSecondPass); - num_started += kNumBackendsSecondPass; - // Check client stats. + // Wait for queries to start going to one of the new backends. + // This tells us that we're now using the new serverlist. + std::tie(num_ok, num_failure, num_drops) = + WaitForAllBackends(/* start_index */ kNumBackendsFirstPass); + num_started += num_ok + num_failure + num_drops; + // Send one RPC per backend. + CheckRpcSendOk(kNumBackendsSecondPass); + num_started += kNumBackendsSecondPass; + // Check client stats. load_report = balancers_[0]->lrs_service()->WaitForLoadReport(); ASSERT_EQ(load_report.size(), 1UL); client_stats = std::move(load_report.front()); @@ -5625,62 +5625,62 @@ TEST_P(ClientLoadReportingTest, BalancerRestart) { EXPECT_EQ(0U, client_stats.total_requests_in_progress()); EXPECT_EQ(0U, client_stats.total_error_requests()); EXPECT_EQ(0U, client_stats.total_dropped_requests()); -} - -class ClientLoadReportingWithDropTest : public XdsEnd2endTest { - public: - ClientLoadReportingWithDropTest() : XdsEnd2endTest(4, 1, 20) {} -}; - -// Tests that the drop stats are correctly reported by client load reporting. -TEST_P(ClientLoadReportingWithDropTest, Vanilla) { +} + +class ClientLoadReportingWithDropTest : public XdsEnd2endTest { + public: + ClientLoadReportingWithDropTest() : XdsEnd2endTest(4, 1, 20) {} +}; + +// Tests that the drop stats are correctly reported by client load reporting. +TEST_P(ClientLoadReportingWithDropTest, Vanilla) { if (!GetParam().use_xds_resolver()) { balancers_[0]->lrs_service()->set_cluster_names({kServerName}); } - SetNextResolution({}); - SetNextResolutionForLbChannelAllBalancers(); - const size_t kNumRpcs = 3000; - const uint32_t kDropPerMillionForLb = 100000; - const uint32_t kDropPerMillionForThrottle = 200000; - const double kDropRateForLb = kDropPerMillionForLb / 1000000.0; - const double kDropRateForThrottle = kDropPerMillionForThrottle / 1000000.0; - const double KDropRateForLbAndThrottle = - kDropRateForLb + (1 - kDropRateForLb) * kDropRateForThrottle; - // The ADS response contains two drop categories. + SetNextResolution({}); + SetNextResolutionForLbChannelAllBalancers(); + const size_t kNumRpcs = 3000; + const uint32_t kDropPerMillionForLb = 100000; + const uint32_t kDropPerMillionForThrottle = 200000; + const double kDropRateForLb = kDropPerMillionForLb / 1000000.0; + const double kDropRateForThrottle = kDropPerMillionForThrottle / 1000000.0; + const double KDropRateForLbAndThrottle = + kDropRateForLb + (1 - kDropRateForLb) * kDropRateForThrottle; + // The ADS response contains two drop categories. AdsServiceImpl::EdsResourceArgs args({ - {"locality0", GetBackendPorts()}, - }); - args.drop_categories = {{kLbDropType, kDropPerMillionForLb}, - {kThrottleDropType, kDropPerMillionForThrottle}}; + {"locality0", GetBackendPorts()}, + }); + args.drop_categories = {{kLbDropType, kDropPerMillionForLb}, + {kThrottleDropType, kDropPerMillionForThrottle}}; balancers_[0]->ads_service()->SetEdsResource( AdsServiceImpl::BuildEdsResource(args, DefaultEdsServiceName())); - int num_ok = 0; - int num_failure = 0; - int num_drops = 0; - std::tie(num_ok, num_failure, num_drops) = WaitForAllBackends(); - const size_t num_warmup = num_ok + num_failure + num_drops; - // Send kNumRpcs RPCs and count the drops. - for (size_t i = 0; i < kNumRpcs; ++i) { - EchoResponse response; + int num_ok = 0; + int num_failure = 0; + int num_drops = 0; + std::tie(num_ok, num_failure, num_drops) = WaitForAllBackends(); + const size_t num_warmup = num_ok + num_failure + num_drops; + // Send kNumRpcs RPCs and count the drops. + for (size_t i = 0; i < kNumRpcs; ++i) { + EchoResponse response; const Status status = SendRpc(RpcOptions(), &response); - if (!status.ok() && - status.error_message() == "Call dropped by load balancing policy") { - ++num_drops; - } else { - EXPECT_TRUE(status.ok()) << "code=" << status.error_code() - << " message=" << status.error_message(); + if (!status.ok() && + status.error_message() == "Call dropped by load balancing policy") { + ++num_drops; + } else { + EXPECT_TRUE(status.ok()) << "code=" << status.error_code() + << " message=" << status.error_message(); EXPECT_EQ(response.message(), kRequestMessage); - } - } - // The drop rate should be roughly equal to the expectation. - const double seen_drop_rate = static_cast<double>(num_drops) / kNumRpcs; - const double kErrorTolerance = 0.2; - EXPECT_THAT( - seen_drop_rate, - ::testing::AllOf( - ::testing::Ge(KDropRateForLbAndThrottle * (1 - kErrorTolerance)), - ::testing::Le(KDropRateForLbAndThrottle * (1 + kErrorTolerance)))); - // Check client stats. + } + } + // The drop rate should be roughly equal to the expectation. + const double seen_drop_rate = static_cast<double>(num_drops) / kNumRpcs; + const double kErrorTolerance = 0.2; + EXPECT_THAT( + seen_drop_rate, + ::testing::AllOf( + ::testing::Ge(KDropRateForLbAndThrottle * (1 - kErrorTolerance)), + ::testing::Le(KDropRateForLbAndThrottle * (1 + kErrorTolerance)))); + // Check client stats. const size_t total_rpc = num_warmup + kNumRpcs; ClientStats client_stats; do { @@ -5693,44 +5693,44 @@ TEST_P(ClientLoadReportingWithDropTest, Vanilla) { client_stats.total_dropped_requests() < total_rpc); EXPECT_EQ(num_drops, client_stats.total_dropped_requests()); - EXPECT_THAT( + EXPECT_THAT( client_stats.dropped_requests(kLbDropType), - ::testing::AllOf( - ::testing::Ge(total_rpc * kDropRateForLb * (1 - kErrorTolerance)), - ::testing::Le(total_rpc * kDropRateForLb * (1 + kErrorTolerance)))); + ::testing::AllOf( + ::testing::Ge(total_rpc * kDropRateForLb * (1 - kErrorTolerance)), + ::testing::Le(total_rpc * kDropRateForLb * (1 + kErrorTolerance)))); EXPECT_THAT(client_stats.dropped_requests(kThrottleDropType), - ::testing::AllOf( - ::testing::Ge(total_rpc * (1 - kDropRateForLb) * - kDropRateForThrottle * (1 - kErrorTolerance)), - ::testing::Le(total_rpc * (1 - kDropRateForLb) * - kDropRateForThrottle * (1 + kErrorTolerance)))); -} - + ::testing::AllOf( + ::testing::Ge(total_rpc * (1 - kDropRateForLb) * + kDropRateForThrottle * (1 - kErrorTolerance)), + ::testing::Le(total_rpc * (1 - kDropRateForLb) * + kDropRateForThrottle * (1 + kErrorTolerance)))); +} + TString TestTypeName(const ::testing::TestParamInfo<TestType>& info) { - return info.param.AsString(); -} - + return info.param.AsString(); +} + // TestType params: // - use_xds_resolver // - enable_load_reporting // - enable_rds_testing = false // - use_v2 = false -INSTANTIATE_TEST_SUITE_P(XdsTest, BasicTest, - ::testing::Values(TestType(false, true), - TestType(false, false), +INSTANTIATE_TEST_SUITE_P(XdsTest, BasicTest, + ::testing::Values(TestType(false, true), + TestType(false, false), TestType(true, false), - TestType(true, true)), - &TestTypeName); - + TestType(true, true)), + &TestTypeName); + // Run with both fake resolver and xds resolver. // Don't run with load reporting or v2 or RDS, since they are irrelevant to // the tests. -INSTANTIATE_TEST_SUITE_P(XdsTest, SecureNamingTest, +INSTANTIATE_TEST_SUITE_P(XdsTest, SecureNamingTest, ::testing::Values(TestType(false, false), TestType(true, false)), - &TestTypeName); - + &TestTypeName); + // LDS depends on XdsResolver. INSTANTIATE_TEST_SUITE_P(XdsTest, LdsTest, ::testing::Values(TestType(true, false), @@ -5779,54 +5779,54 @@ INSTANTIATE_TEST_SUITE_P(XdsTest, XdsResolverLoadReportingOnlyTest, ::testing::Values(TestType(true, true)), &TestTypeName); -INSTANTIATE_TEST_SUITE_P(XdsTest, LocalityMapTest, - ::testing::Values(TestType(false, true), - TestType(false, false), +INSTANTIATE_TEST_SUITE_P(XdsTest, LocalityMapTest, + ::testing::Values(TestType(false, true), + TestType(false, false), TestType(true, false), - TestType(true, true)), - &TestTypeName); - -INSTANTIATE_TEST_SUITE_P(XdsTest, FailoverTest, - ::testing::Values(TestType(false, true), - TestType(false, false), + TestType(true, true)), + &TestTypeName); + +INSTANTIATE_TEST_SUITE_P(XdsTest, FailoverTest, + ::testing::Values(TestType(false, true), + TestType(false, false), TestType(true, false), - TestType(true, true)), - &TestTypeName); - -INSTANTIATE_TEST_SUITE_P(XdsTest, DropTest, - ::testing::Values(TestType(false, true), - TestType(false, false), + TestType(true, true)), + &TestTypeName); + +INSTANTIATE_TEST_SUITE_P(XdsTest, DropTest, + ::testing::Values(TestType(false, true), + TestType(false, false), TestType(true, false), - TestType(true, true)), - &TestTypeName); - -INSTANTIATE_TEST_SUITE_P(XdsTest, BalancerUpdateTest, - ::testing::Values(TestType(false, true), - TestType(false, false), - TestType(true, true)), - &TestTypeName); - -// Load reporting tests are not run with load reporting disabled. -INSTANTIATE_TEST_SUITE_P(XdsTest, ClientLoadReportingTest, - ::testing::Values(TestType(false, true), - TestType(true, true)), - &TestTypeName); - -// Load reporting tests are not run with load reporting disabled. -INSTANTIATE_TEST_SUITE_P(XdsTest, ClientLoadReportingWithDropTest, - ::testing::Values(TestType(false, true), - TestType(true, true)), - &TestTypeName); - -} // namespace -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { - grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - grpc::testing::WriteBootstrapFiles(); - grpc::testing::g_port_saver = new grpc::testing::PortSaver(); - const auto result = RUN_ALL_TESTS(); - return result; -} + TestType(true, true)), + &TestTypeName); + +INSTANTIATE_TEST_SUITE_P(XdsTest, BalancerUpdateTest, + ::testing::Values(TestType(false, true), + TestType(false, false), + TestType(true, true)), + &TestTypeName); + +// Load reporting tests are not run with load reporting disabled. +INSTANTIATE_TEST_SUITE_P(XdsTest, ClientLoadReportingTest, + ::testing::Values(TestType(false, true), + TestType(true, true)), + &TestTypeName); + +// Load reporting tests are not run with load reporting disabled. +INSTANTIATE_TEST_SUITE_P(XdsTest, ClientLoadReportingWithDropTest, + ::testing::Values(TestType(false, true), + TestType(true, true)), + &TestTypeName); + +} // namespace +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { + grpc::testing::TestEnvironment env(argc, argv); + ::testing::InitGoogleTest(&argc, argv); + grpc::testing::WriteBootstrapFiles(); + grpc::testing::g_port_saver = new grpc::testing::PortSaver(); + const auto result = RUN_ALL_TESTS(); + return result; +} diff --git a/contrib/libs/grpc/test/cpp/util/byte_buffer_proto_helper.cc b/contrib/libs/grpc/test/cpp/util/byte_buffer_proto_helper.cc index 5971b530750..ed380095986 100644 --- a/contrib/libs/grpc/test/cpp/util/byte_buffer_proto_helper.cc +++ b/contrib/libs/grpc/test/cpp/util/byte_buffer_proto_helper.cc @@ -1,45 +1,45 @@ -/* - * - * Copyright 2016 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 "test/cpp/util/byte_buffer_proto_helper.h" - -namespace grpc { -namespace testing { - -bool ParseFromByteBuffer(ByteBuffer* buffer, grpc::protobuf::Message* message) { - std::vector<Slice> slices; - (void)buffer->Dump(&slices); +/* + * + * Copyright 2016 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 "test/cpp/util/byte_buffer_proto_helper.h" + +namespace grpc { +namespace testing { + +bool ParseFromByteBuffer(ByteBuffer* buffer, grpc::protobuf::Message* message) { + std::vector<Slice> slices; + (void)buffer->Dump(&slices); TString buf; - buf.reserve(buffer->Length()); - for (auto s = slices.begin(); s != slices.end(); s++) { - buf.append(reinterpret_cast<const char*>(s->begin()), s->size()); - } - return message->ParseFromString(buf); -} - -std::unique_ptr<ByteBuffer> SerializeToByteBuffer( - grpc::protobuf::Message* message) { + buf.reserve(buffer->Length()); + for (auto s = slices.begin(); s != slices.end(); s++) { + buf.append(reinterpret_cast<const char*>(s->begin()), s->size()); + } + return message->ParseFromString(buf); +} + +std::unique_ptr<ByteBuffer> SerializeToByteBuffer( + grpc::protobuf::Message* message) { TString buf; - message->SerializeToString(&buf); - Slice slice(buf); - return std::unique_ptr<ByteBuffer>(new ByteBuffer(&slice, 1)); -} - + message->SerializeToString(&buf); + Slice slice(buf); + return std::unique_ptr<ByteBuffer>(new ByteBuffer(&slice, 1)); +} + bool SerializeToByteBufferInPlace(grpc::protobuf::Message* message, ByteBuffer* buffer) { TString buf; @@ -53,5 +53,5 @@ bool SerializeToByteBufferInPlace(grpc::protobuf::Message* message, return true; } -} // namespace testing -} // namespace grpc +} // namespace testing +} // namespace grpc diff --git a/contrib/libs/grpc/test/cpp/util/byte_buffer_proto_helper.h b/contrib/libs/grpc/test/cpp/util/byte_buffer_proto_helper.h index 3d01fb24686..fe6d2770e04 100644 --- a/contrib/libs/grpc/test/cpp/util/byte_buffer_proto_helper.h +++ b/contrib/libs/grpc/test/cpp/util/byte_buffer_proto_helper.h @@ -1,42 +1,42 @@ -/* - * - * Copyright 2016 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. - * - */ - -#ifndef GRPC_TEST_CPP_UTIL_BYTE_BUFFER_PROTO_HELPER_H -#define GRPC_TEST_CPP_UTIL_BYTE_BUFFER_PROTO_HELPER_H - -#include <memory> - -#include <grpcpp/impl/codegen/config_protobuf.h> -#include <grpcpp/support/byte_buffer.h> - -namespace grpc { -namespace testing { - +/* + * + * Copyright 2016 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. + * + */ + +#ifndef GRPC_TEST_CPP_UTIL_BYTE_BUFFER_PROTO_HELPER_H +#define GRPC_TEST_CPP_UTIL_BYTE_BUFFER_PROTO_HELPER_H + +#include <memory> + +#include <grpcpp/impl/codegen/config_protobuf.h> +#include <grpcpp/support/byte_buffer.h> + +namespace grpc { +namespace testing { + bool ParseFromByteBuffer(ByteBuffer* buffer, ::grpc::protobuf::Message* message); - -std::unique_ptr<ByteBuffer> SerializeToByteBuffer( + +std::unique_ptr<ByteBuffer> SerializeToByteBuffer( ::grpc::protobuf::Message* message); - + bool SerializeToByteBufferInPlace(::grpc::protobuf::Message* message, ByteBuffer* buffer); -} // namespace testing -} // namespace grpc - -#endif // GRPC_TEST_CPP_UTIL_BYTE_BUFFER_PROTO_HELPER_H +} // namespace testing +} // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_BYTE_BUFFER_PROTO_HELPER_H diff --git a/contrib/libs/grpc/test/cpp/util/byte_buffer_test.cc b/contrib/libs/grpc/test/cpp/util/byte_buffer_test.cc index c63f351a8f0..8738083ed10 100644 --- a/contrib/libs/grpc/test/cpp/util/byte_buffer_test.cc +++ b/contrib/libs/grpc/test/cpp/util/byte_buffer_test.cc @@ -1,47 +1,47 @@ -/* - * - * 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. - * - */ - -#include <grpc++/support/byte_buffer.h> -#include <grpcpp/impl/grpc_library.h> - -#include <cstring> -#include <vector> - -#include <grpc/grpc.h> -#include <grpc/slice.h> -#include <grpcpp/support/slice.h> -#include <gtest/gtest.h> - +/* + * + * 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. + * + */ + +#include <grpc++/support/byte_buffer.h> +#include <grpcpp/impl/grpc_library.h> + +#include <cstring> +#include <vector> + +#include <grpc/grpc.h> +#include <grpc/slice.h> +#include <grpcpp/support/slice.h> +#include <gtest/gtest.h> + #include "test/core/util/test_config.h" -namespace grpc { - -static internal::GrpcLibraryInitializer g_gli_initializer; - -namespace { - -const char* kContent1 = "hello xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; -const char* kContent2 = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy world"; - +namespace grpc { + +static internal::GrpcLibraryInitializer g_gli_initializer; + +namespace { + +const char* kContent1 = "hello xxxxxxxxxxxxxxxxxxxxxxxxxxxxxx"; +const char* kContent2 = "yyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyyy world"; + class ByteBufferTest : public ::testing::Test { protected: static void SetUpTestCase() { grpc_init(); } - + static void TearDownTestCase() { grpc_shutdown(); } }; @@ -52,83 +52,83 @@ TEST_F(ByteBufferTest, CopyCtor) { EXPECT_FALSE(buffer2.Valid()); } -TEST_F(ByteBufferTest, CreateFromSingleSlice) { - Slice s(kContent1); - ByteBuffer buffer(&s, 1); - EXPECT_EQ(strlen(kContent1), buffer.Length()); -} - -TEST_F(ByteBufferTest, CreateFromVector) { - std::vector<Slice> slices; - slices.emplace_back(kContent1); - slices.emplace_back(kContent2); - ByteBuffer buffer(&slices[0], 2); - EXPECT_EQ(strlen(kContent1) + strlen(kContent2), buffer.Length()); -} - -TEST_F(ByteBufferTest, Clear) { - Slice s(kContent1); - ByteBuffer buffer(&s, 1); - buffer.Clear(); - EXPECT_EQ(static_cast<size_t>(0), buffer.Length()); -} - -TEST_F(ByteBufferTest, Length) { - std::vector<Slice> slices; - slices.emplace_back(kContent1); - slices.emplace_back(kContent2); - ByteBuffer buffer(&slices[0], 2); - EXPECT_EQ(strlen(kContent1) + strlen(kContent2), buffer.Length()); -} - -bool SliceEqual(const Slice& a, grpc_slice b) { - if (a.size() != GRPC_SLICE_LENGTH(b)) { - return false; - } - for (size_t i = 0; i < a.size(); i++) { - if (a.begin()[i] != GRPC_SLICE_START_PTR(b)[i]) { - return false; - } - } - return true; -} - -TEST_F(ByteBufferTest, Dump) { - grpc_slice hello = grpc_slice_from_copied_string(kContent1); - grpc_slice world = grpc_slice_from_copied_string(kContent2); - std::vector<Slice> slices; - slices.push_back(Slice(hello, Slice::STEAL_REF)); - slices.push_back(Slice(world, Slice::STEAL_REF)); - ByteBuffer buffer(&slices[0], 2); - slices.clear(); - (void)buffer.Dump(&slices); - EXPECT_TRUE(SliceEqual(slices[0], hello)); - EXPECT_TRUE(SliceEqual(slices[1], world)); -} - -TEST_F(ByteBufferTest, SerializationMakesCopy) { - grpc_slice hello = grpc_slice_from_copied_string(kContent1); - grpc_slice world = grpc_slice_from_copied_string(kContent2); - std::vector<Slice> slices; - slices.push_back(Slice(hello, Slice::STEAL_REF)); - slices.push_back(Slice(world, Slice::STEAL_REF)); - ByteBuffer send_buffer; - bool owned = false; - ByteBuffer buffer(&slices[0], 2); - slices.clear(); - auto status = SerializationTraits<ByteBuffer, void>::Serialize( - buffer, &send_buffer, &owned); - EXPECT_TRUE(status.ok()); - EXPECT_TRUE(owned); - EXPECT_TRUE(send_buffer.Valid()); -} - -} // namespace -} // namespace grpc - -int main(int argc, char** argv) { +TEST_F(ByteBufferTest, CreateFromSingleSlice) { + Slice s(kContent1); + ByteBuffer buffer(&s, 1); + EXPECT_EQ(strlen(kContent1), buffer.Length()); +} + +TEST_F(ByteBufferTest, CreateFromVector) { + std::vector<Slice> slices; + slices.emplace_back(kContent1); + slices.emplace_back(kContent2); + ByteBuffer buffer(&slices[0], 2); + EXPECT_EQ(strlen(kContent1) + strlen(kContent2), buffer.Length()); +} + +TEST_F(ByteBufferTest, Clear) { + Slice s(kContent1); + ByteBuffer buffer(&s, 1); + buffer.Clear(); + EXPECT_EQ(static_cast<size_t>(0), buffer.Length()); +} + +TEST_F(ByteBufferTest, Length) { + std::vector<Slice> slices; + slices.emplace_back(kContent1); + slices.emplace_back(kContent2); + ByteBuffer buffer(&slices[0], 2); + EXPECT_EQ(strlen(kContent1) + strlen(kContent2), buffer.Length()); +} + +bool SliceEqual(const Slice& a, grpc_slice b) { + if (a.size() != GRPC_SLICE_LENGTH(b)) { + return false; + } + for (size_t i = 0; i < a.size(); i++) { + if (a.begin()[i] != GRPC_SLICE_START_PTR(b)[i]) { + return false; + } + } + return true; +} + +TEST_F(ByteBufferTest, Dump) { + grpc_slice hello = grpc_slice_from_copied_string(kContent1); + grpc_slice world = grpc_slice_from_copied_string(kContent2); + std::vector<Slice> slices; + slices.push_back(Slice(hello, Slice::STEAL_REF)); + slices.push_back(Slice(world, Slice::STEAL_REF)); + ByteBuffer buffer(&slices[0], 2); + slices.clear(); + (void)buffer.Dump(&slices); + EXPECT_TRUE(SliceEqual(slices[0], hello)); + EXPECT_TRUE(SliceEqual(slices[1], world)); +} + +TEST_F(ByteBufferTest, SerializationMakesCopy) { + grpc_slice hello = grpc_slice_from_copied_string(kContent1); + grpc_slice world = grpc_slice_from_copied_string(kContent2); + std::vector<Slice> slices; + slices.push_back(Slice(hello, Slice::STEAL_REF)); + slices.push_back(Slice(world, Slice::STEAL_REF)); + ByteBuffer send_buffer; + bool owned = false; + ByteBuffer buffer(&slices[0], 2); + slices.clear(); + auto status = SerializationTraits<ByteBuffer, void>::Serialize( + buffer, &send_buffer, &owned); + EXPECT_TRUE(status.ok()); + EXPECT_TRUE(owned); + EXPECT_TRUE(send_buffer.Valid()); +} + +} // namespace +} // namespace grpc + +int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - int ret = RUN_ALL_TESTS(); - return ret; -} + ::testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + return ret; +} diff --git a/contrib/libs/grpc/test/cpp/util/channel_trace_proto_helper.cc b/contrib/libs/grpc/test/cpp/util/channel_trace_proto_helper.cc index d4b4026774a..8ecf96a6266 100644 --- a/contrib/libs/grpc/test/cpp/util/channel_trace_proto_helper.cc +++ b/contrib/libs/grpc/test/cpp/util/channel_trace_proto_helper.cc @@ -1,37 +1,37 @@ -/* - * - * 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. - * - */ - +/* + * + * 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/support/port_platform.h> -#include "test/cpp/util/channel_trace_proto_helper.h" - -#include <grpc/grpc.h> -#include <grpc/support/log.h> +#include "test/cpp/util/channel_trace_proto_helper.h" + +#include <grpc/grpc.h> +#include <grpc/support/log.h> #include <grpcpp/impl/codegen/config.h> #include <grpcpp/impl/codegen/config_protobuf.h> -#include <gtest/gtest.h> - +#include <gtest/gtest.h> + #include "src/core/lib/iomgr/error.h" #include "src/core/lib/json/json.h" -#include "src/proto/grpc/channelz/channelz.pb.h" - -namespace grpc { - +#include "src/proto/grpc/channelz/channelz.pb.h" + +namespace grpc { + namespace { // Generic helper that takes in a json string, converts it to a proto, and @@ -41,10 +41,10 @@ template <typename Message> void VaidateProtoJsonTranslation(const TString& json_str) { Message msg; grpc::protobuf::json::JsonParseOptions parse_options; - // If the following line is failing, then uncomment the last line of the - // comment, and uncomment the lines that print the two strings. You can - // then compare the output, and determine what fields are missing. - // + // If the following line is failing, then uncomment the last line of the + // comment, and uncomment the lines that print the two strings. You can + // then compare the output, and determine what fields are missing. + // // parse_options.ignore_unknown_fields = true; grpc::protobuf::util::Status s = grpc::protobuf::json::JsonStringToMessage(json_str, &msg, parse_options); @@ -66,10 +66,10 @@ void VaidateProtoJsonTranslation(const TString& json_str) { proto_json_str = parsed_json.Dump(); // uncomment these to compare the json strings. // gpr_log(GPR_ERROR, "tracer json: %s", json_str.c_str()); - // gpr_log(GPR_ERROR, "proto json: %s", proto_json_str.c_str()); + // gpr_log(GPR_ERROR, "proto json: %s", proto_json_str.c_str()); EXPECT_EQ(json_str, proto_json_str); -} - +} + } // namespace namespace testing { @@ -111,5 +111,5 @@ void ValidateGetServersResponseProtoJsonTranslation(const char* json_c_str) { json_c_str); } -} // namespace testing -} // namespace grpc +} // namespace testing +} // namespace grpc diff --git a/contrib/libs/grpc/test/cpp/util/channel_trace_proto_helper.h b/contrib/libs/grpc/test/cpp/util/channel_trace_proto_helper.h index 664e899deb6..47bfc8c50d2 100644 --- a/contrib/libs/grpc/test/cpp/util/channel_trace_proto_helper.h +++ b/contrib/libs/grpc/test/cpp/util/channel_trace_proto_helper.h @@ -1,27 +1,27 @@ -/* - * - * 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. - * - */ - -#ifndef GRPC_TEST_CPP_UTIL_CHANNEL_TRACE_PROTO_HELPER_H -#define GRPC_TEST_CPP_UTIL_CHANNEL_TRACE_PROTO_HELPER_H - -namespace grpc { -namespace testing { - +/* + * + * 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. + * + */ + +#ifndef GRPC_TEST_CPP_UTIL_CHANNEL_TRACE_PROTO_HELPER_H +#define GRPC_TEST_CPP_UTIL_CHANNEL_TRACE_PROTO_HELPER_H + +namespace grpc { +namespace testing { + void ValidateChannelTraceProtoJsonTranslation(const char* json_c_str); void ValidateChannelProtoJsonTranslation(const char* json_c_str); void ValidateGetTopChannelsResponseProtoJsonTranslation(const char* json_c_str); @@ -30,8 +30,8 @@ void ValidateGetServerResponseProtoJsonTranslation(const char* json_c_str); void ValidateSubchannelProtoJsonTranslation(const char* json_c_str); void ValidateServerProtoJsonTranslation(const char* json_c_str); void ValidateGetServersResponseProtoJsonTranslation(const char* json_c_str); - -} // namespace testing -} // namespace grpc - -#endif // GRPC_TEST_CPP_UTIL_CHANNEL_TRACE_PROTO_HELPER_H + +} // namespace testing +} // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_CHANNEL_TRACE_PROTO_HELPER_H diff --git a/contrib/libs/grpc/test/cpp/util/cli_call.cc b/contrib/libs/grpc/test/cpp/util/cli_call.cc index 5b3631667f8..626f35d57e0 100644 --- a/contrib/libs/grpc/test/cpp/util/cli_call.cc +++ b/contrib/libs/grpc/test/cpp/util/cli_call.cc @@ -1,67 +1,67 @@ -/* - * - * 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. - * - */ - -#include "test/cpp/util/cli_call.h" - -#include <grpc/grpc.h> -#include <grpc/slice.h> -#include <grpc/support/log.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/support/byte_buffer.h> - +/* + * + * 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. + * + */ + +#include "test/cpp/util/cli_call.h" + +#include <grpc/grpc.h> +#include <grpc/slice.h> +#include <grpc/support/log.h> +#include <grpcpp/channel.h> +#include <grpcpp/client_context.h> +#include <grpcpp/support/byte_buffer.h> + #include <cmath> #include <iostream> #include <utility> -namespace grpc { -namespace testing { -namespace { -void* tag(int i) { return (void*)static_cast<intptr_t>(i); } -} // namespace - +namespace grpc { +namespace testing { +namespace { +void* tag(int i) { return (void*)static_cast<intptr_t>(i); } +} // namespace + Status CliCall::Call(const std::shared_ptr<grpc::Channel>& channel, const TString& method, const TString& request, TString* response, - const OutgoingMetadataContainer& metadata, - IncomingMetadataContainer* server_initial_metadata, - IncomingMetadataContainer* server_trailing_metadata) { + const OutgoingMetadataContainer& metadata, + IncomingMetadataContainer* server_initial_metadata, + IncomingMetadataContainer* server_trailing_metadata) { CliCall call(channel, method, metadata); - call.Write(request); - call.WritesDone(); - if (!call.Read(response, server_initial_metadata)) { - fprintf(stderr, "Failed to read response.\n"); - } - return call.Finish(server_trailing_metadata); -} - + call.Write(request); + call.WritesDone(); + if (!call.Read(response, server_initial_metadata)) { + fprintf(stderr, "Failed to read response.\n"); + } + return call.Finish(server_trailing_metadata); +} + CliCall::CliCall(const std::shared_ptr<grpc::Channel>& channel, const TString& method, const OutgoingMetadataContainer& metadata, CliArgs args) - : stub_(new grpc::GenericStub(channel)) { - gpr_mu_init(&write_mu_); - gpr_cv_init(&write_cv_); - if (!metadata.empty()) { - for (OutgoingMetadataContainer::const_iterator iter = metadata.begin(); - iter != metadata.end(); ++iter) { - ctx_.AddMetadata(iter->first, iter->second); - } - } + : stub_(new grpc::GenericStub(channel)) { + gpr_mu_init(&write_mu_); + gpr_cv_init(&write_cv_); + if (!metadata.empty()) { + for (OutgoingMetadataContainer::const_iterator iter = metadata.begin(); + iter != metadata.end(); ++iter) { + ctx_.AddMetadata(iter->first, iter->second); + } + } // Set deadline if timeout > 0 (default value -1 if no timeout specified) if (args.timeout > 0) { @@ -78,152 +78,152 @@ CliCall::CliCall(const std::shared_ptr<grpc::Channel>& channel, "WARNING: Non-positive timeout value, skipping setting deadline.\n"); } - call_ = stub_->PrepareCall(&ctx_, method, &cq_); - call_->StartCall(tag(1)); - void* got_tag; - bool ok; - cq_.Next(&got_tag, &ok); - GPR_ASSERT(ok); -} - -CliCall::~CliCall() { - gpr_cv_destroy(&write_cv_); - gpr_mu_destroy(&write_mu_); -} - + call_ = stub_->PrepareCall(&ctx_, method, &cq_); + call_->StartCall(tag(1)); + void* got_tag; + bool ok; + cq_.Next(&got_tag, &ok); + GPR_ASSERT(ok); +} + +CliCall::~CliCall() { + gpr_cv_destroy(&write_cv_); + gpr_mu_destroy(&write_mu_); +} + void CliCall::Write(const TString& request) { - void* got_tag; - bool ok; - - gpr_slice s = gpr_slice_from_copied_buffer(request.data(), request.size()); - grpc::Slice req_slice(s, grpc::Slice::STEAL_REF); - grpc::ByteBuffer send_buffer(&req_slice, 1); - call_->Write(send_buffer, tag(2)); - cq_.Next(&got_tag, &ok); - GPR_ASSERT(ok); -} - + void* got_tag; + bool ok; + + gpr_slice s = gpr_slice_from_copied_buffer(request.data(), request.size()); + grpc::Slice req_slice(s, grpc::Slice::STEAL_REF); + grpc::ByteBuffer send_buffer(&req_slice, 1); + call_->Write(send_buffer, tag(2)); + cq_.Next(&got_tag, &ok); + GPR_ASSERT(ok); +} + bool CliCall::Read(TString* response, - IncomingMetadataContainer* server_initial_metadata) { - void* got_tag; - bool ok; - - grpc::ByteBuffer recv_buffer; - call_->Read(&recv_buffer, tag(3)); - - if (!cq_.Next(&got_tag, &ok) || !ok) { - return false; - } - std::vector<grpc::Slice> slices; - GPR_ASSERT(recv_buffer.Dump(&slices).ok()); - - response->clear(); - for (size_t i = 0; i < slices.size(); i++) { - response->append(reinterpret_cast<const char*>(slices[i].begin()), - slices[i].size()); - } - if (server_initial_metadata) { - *server_initial_metadata = ctx_.GetServerInitialMetadata(); - } - return true; -} - -void CliCall::WritesDone() { - void* got_tag; - bool ok; - - call_->WritesDone(tag(4)); - cq_.Next(&got_tag, &ok); - GPR_ASSERT(ok); -} - + IncomingMetadataContainer* server_initial_metadata) { + void* got_tag; + bool ok; + + grpc::ByteBuffer recv_buffer; + call_->Read(&recv_buffer, tag(3)); + + if (!cq_.Next(&got_tag, &ok) || !ok) { + return false; + } + std::vector<grpc::Slice> slices; + GPR_ASSERT(recv_buffer.Dump(&slices).ok()); + + response->clear(); + for (size_t i = 0; i < slices.size(); i++) { + response->append(reinterpret_cast<const char*>(slices[i].begin()), + slices[i].size()); + } + if (server_initial_metadata) { + *server_initial_metadata = ctx_.GetServerInitialMetadata(); + } + return true; +} + +void CliCall::WritesDone() { + void* got_tag; + bool ok; + + call_->WritesDone(tag(4)); + cq_.Next(&got_tag, &ok); + GPR_ASSERT(ok); +} + void CliCall::WriteAndWait(const TString& request) { - grpc::Slice req_slice(request); - grpc::ByteBuffer send_buffer(&req_slice, 1); - - gpr_mu_lock(&write_mu_); - call_->Write(send_buffer, tag(2)); - write_done_ = false; - while (!write_done_) { - gpr_cv_wait(&write_cv_, &write_mu_, gpr_inf_future(GPR_CLOCK_MONOTONIC)); - } - gpr_mu_unlock(&write_mu_); -} - -void CliCall::WritesDoneAndWait() { - gpr_mu_lock(&write_mu_); - call_->WritesDone(tag(4)); - write_done_ = false; - while (!write_done_) { - gpr_cv_wait(&write_cv_, &write_mu_, gpr_inf_future(GPR_CLOCK_MONOTONIC)); - } - gpr_mu_unlock(&write_mu_); -} - -bool CliCall::ReadAndMaybeNotifyWrite( + grpc::Slice req_slice(request); + grpc::ByteBuffer send_buffer(&req_slice, 1); + + gpr_mu_lock(&write_mu_); + call_->Write(send_buffer, tag(2)); + write_done_ = false; + while (!write_done_) { + gpr_cv_wait(&write_cv_, &write_mu_, gpr_inf_future(GPR_CLOCK_MONOTONIC)); + } + gpr_mu_unlock(&write_mu_); +} + +void CliCall::WritesDoneAndWait() { + gpr_mu_lock(&write_mu_); + call_->WritesDone(tag(4)); + write_done_ = false; + while (!write_done_) { + gpr_cv_wait(&write_cv_, &write_mu_, gpr_inf_future(GPR_CLOCK_MONOTONIC)); + } + gpr_mu_unlock(&write_mu_); +} + +bool CliCall::ReadAndMaybeNotifyWrite( TString* response, IncomingMetadataContainer* server_initial_metadata) { - void* got_tag; - bool ok; - grpc::ByteBuffer recv_buffer; - - call_->Read(&recv_buffer, tag(3)); - bool cq_result = cq_.Next(&got_tag, &ok); - - while (got_tag != tag(3)) { - gpr_mu_lock(&write_mu_); - write_done_ = true; - gpr_cv_signal(&write_cv_); - gpr_mu_unlock(&write_mu_); - - cq_result = cq_.Next(&got_tag, &ok); - if (got_tag == tag(2)) { - GPR_ASSERT(ok); - } - } - - if (!cq_result || !ok) { - // If the RPC is ended on the server side, we should still wait for the - // pending write on the client side to be done. - if (!ok) { - gpr_mu_lock(&write_mu_); - if (!write_done_) { - cq_.Next(&got_tag, &ok); - GPR_ASSERT(got_tag != tag(2)); - write_done_ = true; - gpr_cv_signal(&write_cv_); - } - gpr_mu_unlock(&write_mu_); - } - return false; - } - - std::vector<grpc::Slice> slices; - GPR_ASSERT(recv_buffer.Dump(&slices).ok()); - response->clear(); - for (size_t i = 0; i < slices.size(); i++) { - response->append(reinterpret_cast<const char*>(slices[i].begin()), - slices[i].size()); - } - if (server_initial_metadata) { - *server_initial_metadata = ctx_.GetServerInitialMetadata(); - } - return true; -} - -Status CliCall::Finish(IncomingMetadataContainer* server_trailing_metadata) { - void* got_tag; - bool ok; - grpc::Status status; - - call_->Finish(&status, tag(5)); - cq_.Next(&got_tag, &ok); - GPR_ASSERT(ok); - if (server_trailing_metadata) { - *server_trailing_metadata = ctx_.GetServerTrailingMetadata(); - } - - return status; -} - -} // namespace testing -} // namespace grpc + void* got_tag; + bool ok; + grpc::ByteBuffer recv_buffer; + + call_->Read(&recv_buffer, tag(3)); + bool cq_result = cq_.Next(&got_tag, &ok); + + while (got_tag != tag(3)) { + gpr_mu_lock(&write_mu_); + write_done_ = true; + gpr_cv_signal(&write_cv_); + gpr_mu_unlock(&write_mu_); + + cq_result = cq_.Next(&got_tag, &ok); + if (got_tag == tag(2)) { + GPR_ASSERT(ok); + } + } + + if (!cq_result || !ok) { + // If the RPC is ended on the server side, we should still wait for the + // pending write on the client side to be done. + if (!ok) { + gpr_mu_lock(&write_mu_); + if (!write_done_) { + cq_.Next(&got_tag, &ok); + GPR_ASSERT(got_tag != tag(2)); + write_done_ = true; + gpr_cv_signal(&write_cv_); + } + gpr_mu_unlock(&write_mu_); + } + return false; + } + + std::vector<grpc::Slice> slices; + GPR_ASSERT(recv_buffer.Dump(&slices).ok()); + response->clear(); + for (size_t i = 0; i < slices.size(); i++) { + response->append(reinterpret_cast<const char*>(slices[i].begin()), + slices[i].size()); + } + if (server_initial_metadata) { + *server_initial_metadata = ctx_.GetServerInitialMetadata(); + } + return true; +} + +Status CliCall::Finish(IncomingMetadataContainer* server_trailing_metadata) { + void* got_tag; + bool ok; + grpc::Status status; + + call_->Finish(&status, tag(5)); + cq_.Next(&got_tag, &ok); + GPR_ASSERT(ok); + if (server_trailing_metadata) { + *server_trailing_metadata = ctx_.GetServerTrailingMetadata(); + } + + return status; +} + +} // namespace testing +} // namespace grpc diff --git a/contrib/libs/grpc/test/cpp/util/cli_call.h b/contrib/libs/grpc/test/cpp/util/cli_call.h index 79d00d99f4a..b3a5a55dc1f 100644 --- a/contrib/libs/grpc/test/cpp/util/cli_call.h +++ b/contrib/libs/grpc/test/cpp/util/cli_call.h @@ -1,51 +1,51 @@ -/* - * - * 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. - * - */ - -#ifndef GRPC_TEST_CPP_UTIL_CLI_CALL_H -#define GRPC_TEST_CPP_UTIL_CLI_CALL_H - -#include <grpcpp/channel.h> -#include <grpcpp/completion_queue.h> -#include <grpcpp/generic/generic_stub.h> -#include <grpcpp/support/status.h> -#include <grpcpp/support/string_ref.h> - +/* + * + * 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. + * + */ + +#ifndef GRPC_TEST_CPP_UTIL_CLI_CALL_H +#define GRPC_TEST_CPP_UTIL_CLI_CALL_H + +#include <grpcpp/channel.h> +#include <grpcpp/completion_queue.h> +#include <grpcpp/generic/generic_stub.h> +#include <grpcpp/support/status.h> +#include <grpcpp/support/string_ref.h> + #include <map> - + namespace grpc { - + class ClientContext; struct CliArgs { double timeout = -1; }; -namespace testing { - -// CliCall handles the sending and receiving of generic messages given the name -// of the remote method. This class is only used by GrpcTool. Its thread-safe -// and thread-unsafe methods should not be used together. -class CliCall final { - public: +namespace testing { + +// CliCall handles the sending and receiving of generic messages given the name +// of the remote method. This class is only used by GrpcTool. Its thread-safe +// and thread-unsafe methods should not be used together. +class CliCall final { + public: typedef std::multimap<TString, TString> OutgoingMetadataContainer; - typedef std::multimap<grpc::string_ref, grpc::string_ref> - IncomingMetadataContainer; - + typedef std::multimap<grpc::string_ref, grpc::string_ref> + IncomingMetadataContainer; + CliCall(const std::shared_ptr<grpc::Channel>& channel, const TString& method, const OutgoingMetadataContainer& metadata, CliArgs args); @@ -53,57 +53,57 @@ class CliCall final { const TString& method, const OutgoingMetadataContainer& metadata) : CliCall(channel, method, metadata, CliArgs{}) {} - ~CliCall(); - - // Perform an unary generic RPC. + ~CliCall(); + + // Perform an unary generic RPC. static Status Call(const std::shared_ptr<grpc::Channel>& channel, const TString& method, const TString& request, TString* response, - const OutgoingMetadataContainer& metadata, - IncomingMetadataContainer* server_initial_metadata, - IncomingMetadataContainer* server_trailing_metadata); - - // Send a generic request message in a synchronous manner. NOT thread-safe. + const OutgoingMetadataContainer& metadata, + IncomingMetadataContainer* server_initial_metadata, + IncomingMetadataContainer* server_trailing_metadata); + + // Send a generic request message in a synchronous manner. NOT thread-safe. void Write(const TString& request); - - // Send a generic request message in a synchronous manner. NOT thread-safe. - void WritesDone(); - - // Receive a generic response message in a synchronous manner.NOT thread-safe. + + // Send a generic request message in a synchronous manner. NOT thread-safe. + void WritesDone(); + + // Receive a generic response message in a synchronous manner.NOT thread-safe. bool Read(TString* response, - IncomingMetadataContainer* server_initial_metadata); - - // Thread-safe write. Must be used with ReadAndMaybeNotifyWrite. Send out a - // generic request message and wait for ReadAndMaybeNotifyWrite to finish it. + IncomingMetadataContainer* server_initial_metadata); + + // Thread-safe write. Must be used with ReadAndMaybeNotifyWrite. Send out a + // generic request message and wait for ReadAndMaybeNotifyWrite to finish it. void WriteAndWait(const TString& request); - - // Thread-safe WritesDone. Must be used with ReadAndMaybeNotifyWrite. Send out - // WritesDone for gereneric request messages and wait for - // ReadAndMaybeNotifyWrite to finish it. - void WritesDoneAndWait(); - - // Thread-safe Read. Blockingly receive a generic response message. Notify - // writes if they are finished when this read is waiting for a resposne. - bool ReadAndMaybeNotifyWrite( + + // Thread-safe WritesDone. Must be used with ReadAndMaybeNotifyWrite. Send out + // WritesDone for gereneric request messages and wait for + // ReadAndMaybeNotifyWrite to finish it. + void WritesDoneAndWait(); + + // Thread-safe Read. Blockingly receive a generic response message. Notify + // writes if they are finished when this read is waiting for a resposne. + bool ReadAndMaybeNotifyWrite( TString* response, - IncomingMetadataContainer* server_initial_metadata); - - // Finish the RPC. - Status Finish(IncomingMetadataContainer* server_trailing_metadata); - + IncomingMetadataContainer* server_initial_metadata); + + // Finish the RPC. + Status Finish(IncomingMetadataContainer* server_trailing_metadata); + TString peer() const { return ctx_.peer(); } - private: - std::unique_ptr<grpc::GenericStub> stub_; + private: + std::unique_ptr<grpc::GenericStub> stub_; grpc::ClientContext ctx_; - std::unique_ptr<grpc::GenericClientAsyncReaderWriter> call_; - grpc::CompletionQueue cq_; - gpr_mu write_mu_; - gpr_cv write_cv_; // Protected by write_mu_; - bool write_done_; // Portected by write_mu_; -}; - -} // namespace testing -} // namespace grpc - -#endif // GRPC_TEST_CPP_UTIL_CLI_CALL_H + std::unique_ptr<grpc::GenericClientAsyncReaderWriter> call_; + grpc::CompletionQueue cq_; + gpr_mu write_mu_; + gpr_cv write_cv_; // Protected by write_mu_; + bool write_done_; // Portected by write_mu_; +}; + +} // namespace testing +} // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_CLI_CALL_H diff --git a/contrib/libs/grpc/test/cpp/util/cli_call_test.cc b/contrib/libs/grpc/test/cpp/util/cli_call_test.cc index 4f0544b2e53..6fb745ffaf7 100644 --- a/contrib/libs/grpc/test/cpp/util/cli_call_test.cc +++ b/contrib/libs/grpc/test/cpp/util/cli_call_test.cc @@ -1,128 +1,128 @@ -/* - * - * 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. - * - */ - -#include "test/cpp/util/cli_call.h" - -#include <grpc/grpc.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> -#include <gtest/gtest.h> - -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/util/string_ref_helper.h" - -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; - -namespace grpc { -namespace testing { - -class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { - public: - Status Echo(ServerContext* context, const EchoRequest* request, - EchoResponse* response) override { - if (!context->client_metadata().empty()) { - for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator - iter = context->client_metadata().begin(); - iter != context->client_metadata().end(); ++iter) { - context->AddInitialMetadata(ToString(iter->first), - ToString(iter->second)); - } - } - context->AddTrailingMetadata("trailing_key", "trailing_value"); - response->set_message(request->message()); - return Status::OK; - } -}; - -class CliCallTest : public ::testing::Test { - protected: - CliCallTest() {} - - void SetUp() override { - int port = grpc_pick_unused_port_or_die(); - server_address_ << "localhost:" << port; - // Setup server - ServerBuilder builder; - builder.AddListeningPort(server_address_.str(), - InsecureServerCredentials()); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); - } - - void TearDown() override { server_->Shutdown(); } - - void ResetStub() { +/* + * + * 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. + * + */ + +#include "test/cpp/util/cli_call.h" + +#include <grpc/grpc.h> +#include <grpcpp/channel.h> +#include <grpcpp/client_context.h> +#include <grpcpp/create_channel.h> +#include <grpcpp/server.h> +#include <grpcpp/server_builder.h> +#include <grpcpp/server_context.h> +#include <gtest/gtest.h> + +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/util/string_ref_helper.h" + +using grpc::testing::EchoRequest; +using grpc::testing::EchoResponse; + +namespace grpc { +namespace testing { + +class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { + public: + Status Echo(ServerContext* context, const EchoRequest* request, + EchoResponse* response) override { + if (!context->client_metadata().empty()) { + for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator + iter = context->client_metadata().begin(); + iter != context->client_metadata().end(); ++iter) { + context->AddInitialMetadata(ToString(iter->first), + ToString(iter->second)); + } + } + context->AddTrailingMetadata("trailing_key", "trailing_value"); + response->set_message(request->message()); + return Status::OK; + } +}; + +class CliCallTest : public ::testing::Test { + protected: + CliCallTest() {} + + void SetUp() override { + int port = grpc_pick_unused_port_or_die(); + server_address_ << "localhost:" << port; + // Setup server + ServerBuilder builder; + builder.AddListeningPort(server_address_.str(), + InsecureServerCredentials()); + builder.RegisterService(&service_); + server_ = builder.BuildAndStart(); + } + + void TearDown() override { server_->Shutdown(); } + + void ResetStub() { channel_ = grpc::CreateChannel(server_address_.str(), InsecureChannelCredentials()); - stub_ = grpc::testing::EchoTestService::NewStub(channel_); - } - - std::shared_ptr<Channel> channel_; - std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; - std::unique_ptr<Server> server_; - std::ostringstream server_address_; - TestServiceImpl service_; -}; - -// Send a rpc with a normal stub and then a CliCall. Verify they match. -TEST_F(CliCallTest, SimpleRpc) { - ResetStub(); - // Normal stub. - EchoRequest request; - EchoResponse response; - request.set_message("Hello"); - - ClientContext context; - context.AddMetadata("key1", "val1"); - Status s = stub_->Echo(&context, request, &response); - EXPECT_EQ(response.message(), request.message()); - EXPECT_TRUE(s.ok()); - + stub_ = grpc::testing::EchoTestService::NewStub(channel_); + } + + std::shared_ptr<Channel> channel_; + std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_; + std::unique_ptr<Server> server_; + std::ostringstream server_address_; + TestServiceImpl service_; +}; + +// Send a rpc with a normal stub and then a CliCall. Verify they match. +TEST_F(CliCallTest, SimpleRpc) { + ResetStub(); + // Normal stub. + EchoRequest request; + EchoResponse response; + request.set_message("Hello"); + + ClientContext context; + context.AddMetadata("key1", "val1"); + Status s = stub_->Echo(&context, request, &response); + EXPECT_EQ(response.message(), request.message()); + EXPECT_TRUE(s.ok()); + const TString kMethod("/grpc.testing.EchoTestService/Echo"); TString request_bin, response_bin, expected_response_bin; - EXPECT_TRUE(request.SerializeToString(&request_bin)); - EXPECT_TRUE(response.SerializeToString(&expected_response_bin)); + EXPECT_TRUE(request.SerializeToString(&request_bin)); + EXPECT_TRUE(response.SerializeToString(&expected_response_bin)); std::multimap<TString, TString> client_metadata; - std::multimap<grpc::string_ref, grpc::string_ref> server_initial_metadata, - server_trailing_metadata; + std::multimap<grpc::string_ref, grpc::string_ref> server_initial_metadata, + server_trailing_metadata; client_metadata.insert(std::pair<TString, TString>("key1", "val1")); - Status s2 = CliCall::Call(channel_, kMethod, request_bin, &response_bin, - client_metadata, &server_initial_metadata, - &server_trailing_metadata); - EXPECT_TRUE(s2.ok()); - - EXPECT_EQ(expected_response_bin, response_bin); - EXPECT_EQ(context.GetServerInitialMetadata(), server_initial_metadata); - EXPECT_EQ(context.GetServerTrailingMetadata(), server_trailing_metadata); -} - -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { + Status s2 = CliCall::Call(channel_, kMethod, request_bin, &response_bin, + client_metadata, &server_initial_metadata, + &server_trailing_metadata); + EXPECT_TRUE(s2.ok()); + + EXPECT_EQ(expected_response_bin, response_bin); + EXPECT_EQ(context.GetServerInitialMetadata(), server_initial_metadata); + EXPECT_EQ(context.GetServerTrailingMetadata(), server_trailing_metadata); +} + +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/contrib/libs/grpc/test/cpp/util/cli_credentials.cc b/contrib/libs/grpc/test/cpp/util/cli_credentials.cc index efd548eb9b3..465a237d2a2 100644 --- a/contrib/libs/grpc/test/cpp/util/cli_credentials.cc +++ b/contrib/libs/grpc/test/cpp/util/cli_credentials.cc @@ -1,28 +1,28 @@ -/* - * - * Copyright 2016 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 "test/cpp/util/cli_credentials.h" - -#include <gflags/gflags.h> +/* + * + * Copyright 2016 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 "test/cpp/util/cli_credentials.h" + +#include <gflags/gflags.h> #include <grpc/slice.h> #include <grpc/support/log.h> #include <grpcpp/impl/codegen/slice.h> - + #include "src/core/lib/iomgr/load_file.h" DEFINE_bool( @@ -31,8 +31,8 @@ DEFINE_bool( DEFINE_bool(use_auth, false, "Whether to create default google credentials. Deprecated. Use " "--channel_creds_type=gdc."); -DEFINE_string( - access_token, "", +DEFINE_string( + access_token, "", "The access token that will be sent to the server to authenticate RPCs. " "Deprecated. Use --call_creds=access_token=<token>."); DEFINE_string( @@ -59,12 +59,12 @@ DEFINE_string( call_creds, "", "Call credentials to use: none (default), or access_token=<token>. If " "provided, the call creds are composited on top of channel creds."); - -namespace grpc { -namespace testing { - + +namespace grpc { +namespace testing { + namespace { - + const char ACCESS_TOKEN_PREFIX[] = "access_token="; constexpr int ACCESS_TOKEN_PREFIX_LEN = sizeof(ACCESS_TOKEN_PREFIX) / sizeof(*ACCESS_TOKEN_PREFIX) - 1; @@ -77,10 +77,10 @@ bool IsAccessToken(const TString& auth) { TString AccessToken(const TString& auth) { if (!IsAccessToken(auth)) { return ""; - } + } return TString(auth.c_str(), ACCESS_TOKEN_PREFIX_LEN); } - + } // namespace TString CliCredentials::GetDefaultChannelCredsType() const { @@ -138,7 +138,7 @@ CliCredentials::GetChannelCredentials() const { } return grpc::SslCredentials(ssl_creds_options); } else if (FLAGS_channel_creds_type.compare("gdc") == 0) { - return grpc::GoogleDefaultCredentials(); + return grpc::GoogleDefaultCredentials(); } else if (FLAGS_channel_creds_type.compare("alts") == 0) { return grpc::experimental::AltsCredentials( grpc::experimental::AltsCredentialsOptions()); @@ -152,19 +152,19 @@ CliCredentials::GetChannelCredentials() const { "--local_connect_type=%s invalid; must be local_tcp or uds.\n", FLAGS_local_connect_type.c_str()); } - } + } fprintf(stderr, "--channel_creds_type=%s invalid; must be insecure, ssl, gdc, " "alts, or local.\n", FLAGS_channel_creds_type.c_str()); return std::shared_ptr<grpc::ChannelCredentials>(); } - + std::shared_ptr<grpc::CallCredentials> CliCredentials::GetCallCredentials() const { if (IsAccessToken(FLAGS_call_creds.c_str())) { return grpc::AccessTokenCredentials(AccessToken(FLAGS_call_creds.c_str())); - } + } if (FLAGS_call_creds.compare("none") == 0) { // Nothing to do; creds, if any, are baked into the channel. return std::shared_ptr<grpc::CallCredentials>(); @@ -175,7 +175,7 @@ std::shared_ptr<grpc::CallCredentials> CliCredentials::GetCallCredentials() FLAGS_call_creds.c_str()); return std::shared_ptr<grpc::CallCredentials>(); } - + std::shared_ptr<grpc::ChannelCredentials> CliCredentials::GetCredentials() const { if (FLAGS_call_creds.empty()) { @@ -214,15 +214,15 @@ std::shared_ptr<grpc::ChannelCredentials> CliCredentials::GetCredentials() return (channel_creds == nullptr || call_creds == nullptr) ? channel_creds : grpc::CompositeChannelCredentials(channel_creds, call_creds); -} - +} + const TString CliCredentials::GetCredentialUsage() const { return " --enable_ssl ; Set whether to use ssl " "(deprecated)\n" - " --use_auth ; Set whether to create default google" - " credentials\n" + " --use_auth ; Set whether to create default google" + " credentials\n" " ; (deprecated)\n" - " --access_token ; Set the access token in metadata," + " --access_token ; Set the access token in metadata," " overrides --use_auth\n" " ; (deprecated)\n" " --ssl_target ; Set server host for ssl validation\n" @@ -233,7 +233,7 @@ const TString CliCredentials::GetCredentialUsage() const { "local\n" " --call_creds ; Set to none, or" " access_token=<token>\n"; -} +} const TString CliCredentials::GetSslTargetNameOverride() const { bool use_ssl = FLAGS_channel_creds_type.compare("ssl") == 0 || @@ -241,5 +241,5 @@ const TString CliCredentials::GetSslTargetNameOverride() const { return use_ssl ? FLAGS_ssl_target : ""; } -} // namespace testing -} // namespace grpc +} // namespace testing +} // namespace grpc diff --git a/contrib/libs/grpc/test/cpp/util/cli_credentials.h b/contrib/libs/grpc/test/cpp/util/cli_credentials.h index 3e695692fa6..9e18933280e 100644 --- a/contrib/libs/grpc/test/cpp/util/cli_credentials.h +++ b/contrib/libs/grpc/test/cpp/util/cli_credentials.h @@ -1,33 +1,33 @@ -/* - * - * Copyright 2016 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. - * - */ - -#ifndef GRPC_TEST_CPP_UTIL_CLI_CREDENTIALS_H -#define GRPC_TEST_CPP_UTIL_CLI_CREDENTIALS_H - -#include <grpcpp/security/credentials.h> -#include <grpcpp/support/config.h> - -namespace grpc { -namespace testing { - -class CliCredentials { - public: - virtual ~CliCredentials() {} +/* + * + * Copyright 2016 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. + * + */ + +#ifndef GRPC_TEST_CPP_UTIL_CLI_CREDENTIALS_H +#define GRPC_TEST_CPP_UTIL_CLI_CREDENTIALS_H + +#include <grpcpp/security/credentials.h> +#include <grpcpp/support/config.h> + +namespace grpc { +namespace testing { + +class CliCredentials { + public: + virtual ~CliCredentials() {} std::shared_ptr<grpc::ChannelCredentials> GetCredentials() const; virtual const TString GetCredentialUsage() const; virtual const TString GetSslTargetNameOverride() const; @@ -47,9 +47,9 @@ class CliCredentials { // credentials. Child classes can override to support additional // authentication flags unknown to this base class. virtual std::shared_ptr<grpc::CallCredentials> GetCallCredentials() const; -}; - -} // namespace testing -} // namespace grpc - -#endif // GRPC_TEST_CPP_UTIL_CLI_CREDENTIALS_H +}; + +} // namespace testing +} // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_CLI_CREDENTIALS_H diff --git a/contrib/libs/grpc/test/cpp/util/config_grpc_cli.h b/contrib/libs/grpc/test/cpp/util/config_grpc_cli.h index 358884196df..731e6c44581 100644 --- a/contrib/libs/grpc/test/cpp/util/config_grpc_cli.h +++ b/contrib/libs/grpc/test/cpp/util/config_grpc_cli.h @@ -1,70 +1,70 @@ -/* - * - * Copyright 2016 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. - * - */ - -#ifndef GRPC_TEST_CPP_UTIL_CONFIG_GRPC_CLI_H -#define GRPC_TEST_CPP_UTIL_CONFIG_GRPC_CLI_H - -#include <grpcpp/impl/codegen/config_protobuf.h> - -#ifndef GRPC_CUSTOM_DYNAMICMESSAGEFACTORY +/* + * + * Copyright 2016 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. + * + */ + +#ifndef GRPC_TEST_CPP_UTIL_CONFIG_GRPC_CLI_H +#define GRPC_TEST_CPP_UTIL_CONFIG_GRPC_CLI_H + +#include <grpcpp/impl/codegen/config_protobuf.h> + +#ifndef GRPC_CUSTOM_DYNAMICMESSAGEFACTORY #include <google/protobuf/dynamic_message.h> -#define GRPC_CUSTOM_DYNAMICMESSAGEFACTORY \ - ::google::protobuf::DynamicMessageFactory -#endif - -#ifndef GRPC_CUSTOM_DESCRIPTORPOOLDATABASE +#define GRPC_CUSTOM_DYNAMICMESSAGEFACTORY \ + ::google::protobuf::DynamicMessageFactory +#endif + +#ifndef GRPC_CUSTOM_DESCRIPTORPOOLDATABASE #include <google/protobuf/descriptor.h> -#define GRPC_CUSTOM_DESCRIPTORPOOLDATABASE \ - ::google::protobuf::DescriptorPoolDatabase -#define GRPC_CUSTOM_MERGEDDESCRIPTORDATABASE \ - ::google::protobuf::MergedDescriptorDatabase -#endif - -#ifndef GRPC_CUSTOM_TEXTFORMAT +#define GRPC_CUSTOM_DESCRIPTORPOOLDATABASE \ + ::google::protobuf::DescriptorPoolDatabase +#define GRPC_CUSTOM_MERGEDDESCRIPTORDATABASE \ + ::google::protobuf::MergedDescriptorDatabase +#endif + +#ifndef GRPC_CUSTOM_TEXTFORMAT #include <google/protobuf/text_format.h> -#define GRPC_CUSTOM_TEXTFORMAT ::google::protobuf::TextFormat -#endif - -#ifndef GRPC_CUSTOM_DISKSOURCETREE +#define GRPC_CUSTOM_TEXTFORMAT ::google::protobuf::TextFormat +#endif + +#ifndef GRPC_CUSTOM_DISKSOURCETREE #include <google/protobuf/compiler/importer.h> -#define GRPC_CUSTOM_DISKSOURCETREE ::google::protobuf::compiler::DiskSourceTree -#define GRPC_CUSTOM_IMPORTER ::google::protobuf::compiler::Importer -#define GRPC_CUSTOM_MULTIFILEERRORCOLLECTOR \ - ::google::protobuf::compiler::MultiFileErrorCollector -#endif - -namespace grpc { -namespace protobuf { - -typedef GRPC_CUSTOM_DYNAMICMESSAGEFACTORY DynamicMessageFactory; - -typedef GRPC_CUSTOM_DESCRIPTORPOOLDATABASE DescriptorPoolDatabase; -typedef GRPC_CUSTOM_MERGEDDESCRIPTORDATABASE MergedDescriptorDatabase; - -typedef GRPC_CUSTOM_TEXTFORMAT TextFormat; - -namespace compiler { -typedef GRPC_CUSTOM_DISKSOURCETREE DiskSourceTree; -typedef GRPC_CUSTOM_IMPORTER Importer; -typedef GRPC_CUSTOM_MULTIFILEERRORCOLLECTOR MultiFileErrorCollector; -} // namespace compiler - -} // namespace protobuf -} // namespace grpc - -#endif // GRPC_TEST_CPP_UTIL_CONFIG_GRPC_CLI_H +#define GRPC_CUSTOM_DISKSOURCETREE ::google::protobuf::compiler::DiskSourceTree +#define GRPC_CUSTOM_IMPORTER ::google::protobuf::compiler::Importer +#define GRPC_CUSTOM_MULTIFILEERRORCOLLECTOR \ + ::google::protobuf::compiler::MultiFileErrorCollector +#endif + +namespace grpc { +namespace protobuf { + +typedef GRPC_CUSTOM_DYNAMICMESSAGEFACTORY DynamicMessageFactory; + +typedef GRPC_CUSTOM_DESCRIPTORPOOLDATABASE DescriptorPoolDatabase; +typedef GRPC_CUSTOM_MERGEDDESCRIPTORDATABASE MergedDescriptorDatabase; + +typedef GRPC_CUSTOM_TEXTFORMAT TextFormat; + +namespace compiler { +typedef GRPC_CUSTOM_DISKSOURCETREE DiskSourceTree; +typedef GRPC_CUSTOM_IMPORTER Importer; +typedef GRPC_CUSTOM_MULTIFILEERRORCOLLECTOR MultiFileErrorCollector; +} // namespace compiler + +} // namespace protobuf +} // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_CONFIG_GRPC_CLI_H diff --git a/contrib/libs/grpc/test/cpp/util/create_test_channel.cc b/contrib/libs/grpc/test/cpp/util/create_test_channel.cc index 86d8e22af1d..2b0b4f2f4c3 100644 --- a/contrib/libs/grpc/test/cpp/util/create_test_channel.cc +++ b/contrib/libs/grpc/test/cpp/util/create_test_channel.cc @@ -1,31 +1,31 @@ -/* - * - * Copyright 2015-2016 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 "test/cpp/util/create_test_channel.h" - +/* + * + * Copyright 2015-2016 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 "test/cpp/util/create_test_channel.h" + #include <gflags/gflags.h> -#include <grpc/support/log.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/security/credentials.h> - -#include "test/cpp/util/test_credentials_provider.h" - +#include <grpc/support/log.h> +#include <grpcpp/create_channel.h> +#include <grpcpp/security/credentials.h> + +#include "test/cpp/util/test_credentials_provider.h" + DEFINE_string( grpc_test_use_grpclb_with_child_policy, "", "If non-empty, set a static service config on channels created by " @@ -33,31 +33,31 @@ DEFINE_string( "with a child policy being the value of this flag (e.g. round_robin " "or pick_first)."); -namespace grpc { - -namespace { - -const char kProdTlsCredentialsType[] = "prod_ssl"; - -class SslCredentialProvider : public testing::CredentialTypeProvider { - public: - std::shared_ptr<ChannelCredentials> GetChannelCredentials( +namespace grpc { + +namespace { + +const char kProdTlsCredentialsType[] = "prod_ssl"; + +class SslCredentialProvider : public testing::CredentialTypeProvider { + public: + std::shared_ptr<ChannelCredentials> GetChannelCredentials( grpc::ChannelArguments* /*args*/) override { return grpc::SslCredentials(SslCredentialsOptions()); - } - std::shared_ptr<ServerCredentials> GetServerCredentials() override { - return nullptr; - } -}; - -gpr_once g_once_init_add_prod_ssl_provider = GPR_ONCE_INIT; -// Register ssl with non-test roots type to the credentials provider. -void AddProdSslType() { - testing::GetCredentialsProvider()->AddSecureType( - kProdTlsCredentialsType, std::unique_ptr<testing::CredentialTypeProvider>( - new SslCredentialProvider)); -} - + } + std::shared_ptr<ServerCredentials> GetServerCredentials() override { + return nullptr; + } +}; + +gpr_once g_once_init_add_prod_ssl_provider = GPR_ONCE_INIT; +// Register ssl with non-test roots type to the credentials provider. +void AddProdSslType() { + testing::GetCredentialsProvider()->AddSecureType( + kProdTlsCredentialsType, std::unique_ptr<testing::CredentialTypeProvider>( + new SslCredentialProvider)); +} + void MaybeSetCustomChannelArgs(grpc::ChannelArguments* args) { if (FLAGS_grpc_test_use_grpclb_with_child_policy.size() > 0) { args->SetString("grpc.service_config", @@ -68,28 +68,28 @@ void MaybeSetCustomChannelArgs(grpc::ChannelArguments* args) { } } -} // namespace - -// When cred_type is 'ssl', if server is empty, override_hostname is used to -// create channel. Otherwise, connect to server and override hostname if -// override_hostname is provided. -// When cred_type is not 'ssl', override_hostname is ignored. -// Set use_prod_root to true to use the SSL root for connecting to google. -// In this case, path to the roots pem file must be set via environment variable -// GRPC_DEFAULT_SSL_ROOTS_FILE_PATH. -// Otherwise, root for test SSL cert will be used. -// creds will be used to create a channel when cred_type is 'ssl'. -// Use examples: -// CreateTestChannel( -// "1.1.1.1:12345", "ssl", "override.hostname.com", false, creds); -// CreateTestChannel("test.google.com:443", "ssl", "", true, creds); -// same as above -// CreateTestChannel("", "ssl", "test.google.com:443", true, creds); -std::shared_ptr<Channel> CreateTestChannel( +} // namespace + +// When cred_type is 'ssl', if server is empty, override_hostname is used to +// create channel. Otherwise, connect to server and override hostname if +// override_hostname is provided. +// When cred_type is not 'ssl', override_hostname is ignored. +// Set use_prod_root to true to use the SSL root for connecting to google. +// In this case, path to the roots pem file must be set via environment variable +// GRPC_DEFAULT_SSL_ROOTS_FILE_PATH. +// Otherwise, root for test SSL cert will be used. +// creds will be used to create a channel when cred_type is 'ssl'. +// Use examples: +// CreateTestChannel( +// "1.1.1.1:12345", "ssl", "override.hostname.com", false, creds); +// CreateTestChannel("test.google.com:443", "ssl", "", true, creds); +// same as above +// CreateTestChannel("", "ssl", "test.google.com:443", true, creds); +std::shared_ptr<Channel> CreateTestChannel( const TString& server, const TString& cred_type, const TString& override_hostname, bool use_prod_roots, - const std::shared_ptr<CallCredentials>& creds, - const ChannelArguments& args) { + const std::shared_ptr<CallCredentials>& creds, + const ChannelArguments& args) { return CreateTestChannel(server, cred_type, override_hostname, use_prod_roots, creds, args, /*interceptor_creators=*/{}); @@ -148,10 +148,10 @@ std::shared_ptr<Channel> CreateTestChannel( std::vector< std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> interceptor_creators) { - ChannelArguments channel_args(args); + ChannelArguments channel_args(args); MaybeSetCustomChannelArgs(&channel_args); - std::shared_ptr<ChannelCredentials> channel_creds; - if (cred_type.empty()) { + std::shared_ptr<ChannelCredentials> channel_creds; + if (cred_type.empty()) { if (interceptor_creators.empty()) { return ::grpc::CreateCustomChannel(server, InsecureChannelCredentials(), channel_args); @@ -160,25 +160,25 @@ std::shared_ptr<Channel> CreateTestChannel( server, InsecureChannelCredentials(), channel_args, std::move(interceptor_creators)); } - } else if (cred_type == testing::kTlsCredentialsType) { // cred_type == "ssl" - if (use_prod_roots) { - gpr_once_init(&g_once_init_add_prod_ssl_provider, &AddProdSslType); - channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials( - kProdTlsCredentialsType, &channel_args); - if (!server.empty() && !override_hostname.empty()) { - channel_args.SetSslTargetNameOverride(override_hostname); - } - } else { - // override_hostname is discarded as the provider handles it. - channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials( - testing::kTlsCredentialsType, &channel_args); - } - GPR_ASSERT(channel_creds != nullptr); - + } else if (cred_type == testing::kTlsCredentialsType) { // cred_type == "ssl" + if (use_prod_roots) { + gpr_once_init(&g_once_init_add_prod_ssl_provider, &AddProdSslType); + channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials( + kProdTlsCredentialsType, &channel_args); + if (!server.empty() && !override_hostname.empty()) { + channel_args.SetSslTargetNameOverride(override_hostname); + } + } else { + // override_hostname is discarded as the provider handles it. + channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials( + testing::kTlsCredentialsType, &channel_args); + } + GPR_ASSERT(channel_creds != nullptr); + const TString& connect_to = server.empty() ? override_hostname : server; - if (creds.get()) { + if (creds.get()) { channel_creds = grpc::CompositeChannelCredentials(channel_creds, creds); - } + } if (interceptor_creators.empty()) { return ::grpc::CreateCustomChannel(connect_to, channel_creds, channel_args); @@ -187,66 +187,66 @@ std::shared_ptr<Channel> CreateTestChannel( connect_to, channel_creds, channel_args, std::move(interceptor_creators)); } - } else { - channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials( - cred_type, &channel_args); - GPR_ASSERT(channel_creds != nullptr); - + } else { + channel_creds = testing::GetCredentialsProvider()->GetChannelCredentials( + cred_type, &channel_args); + GPR_ASSERT(channel_creds != nullptr); + if (interceptor_creators.empty()) { return ::grpc::CreateCustomChannel(server, channel_creds, channel_args); } else { return experimental::CreateCustomChannelWithInterceptors( server, channel_creds, channel_args, std::move(interceptor_creators)); } - } -} - -std::shared_ptr<Channel> CreateTestChannel( + } +} + +std::shared_ptr<Channel> CreateTestChannel( const TString& server, const TString& override_hostname, - testing::transport_security security_type, bool use_prod_roots, + testing::transport_security security_type, bool use_prod_roots, const std::shared_ptr<CallCredentials>& creds, const ChannelArguments& args, std::vector< std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> interceptor_creators) { TString credential_type = - security_type == testing::ALTS - ? testing::kAltsCredentialsType - : (security_type == testing::TLS ? testing::kTlsCredentialsType - : testing::kInsecureCredentialsType); + security_type == testing::ALTS + ? testing::kAltsCredentialsType + : (security_type == testing::TLS ? testing::kTlsCredentialsType + : testing::kInsecureCredentialsType); return CreateTestChannel(server, credential_type, override_hostname, use_prod_roots, creds, args, std::move(interceptor_creators)); -} - -std::shared_ptr<Channel> CreateTestChannel( +} + +std::shared_ptr<Channel> CreateTestChannel( const TString& server, const TString& override_hostname, - testing::transport_security security_type, bool use_prod_roots, + testing::transport_security security_type, bool use_prod_roots, const std::shared_ptr<CallCredentials>& creds, std::vector< std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> interceptor_creators) { - return CreateTestChannel(server, override_hostname, security_type, + return CreateTestChannel(server, override_hostname, security_type, use_prod_roots, creds, ChannelArguments(), std::move(interceptor_creators)); -} - -std::shared_ptr<Channel> CreateTestChannel( +} + +std::shared_ptr<Channel> CreateTestChannel( const TString& server, const TString& credential_type, const std::shared_ptr<CallCredentials>& creds, std::vector< std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> interceptor_creators) { - ChannelArguments channel_args; + ChannelArguments channel_args; MaybeSetCustomChannelArgs(&channel_args); - std::shared_ptr<ChannelCredentials> channel_creds = - testing::GetCredentialsProvider()->GetChannelCredentials(credential_type, - &channel_args); - GPR_ASSERT(channel_creds != nullptr); - if (creds.get()) { + std::shared_ptr<ChannelCredentials> channel_creds = + testing::GetCredentialsProvider()->GetChannelCredentials(credential_type, + &channel_args); + GPR_ASSERT(channel_creds != nullptr); + if (creds.get()) { channel_creds = grpc::CompositeChannelCredentials(channel_creds, creds); - } + } return experimental::CreateCustomChannelWithInterceptors( server, channel_creds, channel_args, std::move(interceptor_creators)); -} - -} // namespace grpc +} + +} // namespace grpc diff --git a/contrib/libs/grpc/test/cpp/util/create_test_channel.h b/contrib/libs/grpc/test/cpp/util/create_test_channel.h index ed4ce6c11b4..e8637966d21 100644 --- a/contrib/libs/grpc/test/cpp/util/create_test_channel.h +++ b/contrib/libs/grpc/test/cpp/util/create_test_channel.h @@ -1,68 +1,68 @@ -/* - * - * Copyright 2015-2016 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. - * - */ - -#ifndef GRPC_TEST_CPP_UTIL_CREATE_TEST_CHANNEL_H -#define GRPC_TEST_CPP_UTIL_CREATE_TEST_CHANNEL_H - -#include <memory> - +/* + * + * Copyright 2015-2016 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. + * + */ + +#ifndef GRPC_TEST_CPP_UTIL_CREATE_TEST_CHANNEL_H +#define GRPC_TEST_CPP_UTIL_CREATE_TEST_CHANNEL_H + +#include <memory> + #include <grpcpp/channel.h> #include <grpcpp/impl/codegen/client_interceptor.h> -#include <grpcpp/security/credentials.h> +#include <grpcpp/security/credentials.h> #include <grpcpp/support/channel_arguments.h> - + namespace grpc { -class Channel; - -namespace testing { - -typedef enum { INSECURE = 0, TLS, ALTS } transport_security; - -} // namespace testing - -std::shared_ptr<Channel> CreateTestChannel( +class Channel; + +namespace testing { + +typedef enum { INSECURE = 0, TLS, ALTS } transport_security; + +} // namespace testing + +std::shared_ptr<Channel> CreateTestChannel( const TString& server, testing::transport_security security_type); - -std::shared_ptr<Channel> CreateTestChannel( + +std::shared_ptr<Channel> CreateTestChannel( const TString& server, const TString& override_hostname, - testing::transport_security security_type, bool use_prod_roots); - -std::shared_ptr<Channel> CreateTestChannel( + testing::transport_security security_type, bool use_prod_roots); + +std::shared_ptr<Channel> CreateTestChannel( const TString& server, const TString& override_hostname, - testing::transport_security security_type, bool use_prod_roots, - const std::shared_ptr<CallCredentials>& creds); - -std::shared_ptr<Channel> CreateTestChannel( + testing::transport_security security_type, bool use_prod_roots, + const std::shared_ptr<CallCredentials>& creds); + +std::shared_ptr<Channel> CreateTestChannel( const TString& server, const TString& override_hostname, - testing::transport_security security_type, bool use_prod_roots, - const std::shared_ptr<CallCredentials>& creds, - const ChannelArguments& args); - -std::shared_ptr<Channel> CreateTestChannel( + testing::transport_security security_type, bool use_prod_roots, + const std::shared_ptr<CallCredentials>& creds, + const ChannelArguments& args); + +std::shared_ptr<Channel> CreateTestChannel( const TString& server, const TString& cred_type, const TString& override_hostname, bool use_prod_roots, - const std::shared_ptr<CallCredentials>& creds, - const ChannelArguments& args); - -std::shared_ptr<Channel> CreateTestChannel( + const std::shared_ptr<CallCredentials>& creds, + const ChannelArguments& args); + +std::shared_ptr<Channel> CreateTestChannel( const TString& server, const TString& credential_type, - const std::shared_ptr<CallCredentials>& creds); - + const std::shared_ptr<CallCredentials>& creds); + std::shared_ptr<Channel> CreateTestChannel( const TString& server, const TString& override_hostname, testing::transport_security security_type, bool use_prod_roots, @@ -94,6 +94,6 @@ std::shared_ptr<Channel> CreateTestChannel( std::unique_ptr<experimental::ClientInterceptorFactoryInterface>> interceptor_creators); -} // namespace grpc - -#endif // GRPC_TEST_CPP_UTIL_CREATE_TEST_CHANNEL_H +} // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_CREATE_TEST_CHANNEL_H diff --git a/contrib/libs/grpc/test/cpp/util/error_details_test.cc b/contrib/libs/grpc/test/cpp/util/error_details_test.cc index 630ab1d98fa..5135bf28719 100644 --- a/contrib/libs/grpc/test/cpp/util/error_details_test.cc +++ b/contrib/libs/grpc/test/cpp/util/error_details_test.cc @@ -1,125 +1,125 @@ -/* - * - * 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/support/error_details.h> -#include <gtest/gtest.h> - -#include "src/proto/grpc/status/status.pb.h" -#include "src/proto/grpc/testing/echo_messages.pb.h" +/* + * + * 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/support/error_details.h> +#include <gtest/gtest.h> + +#include "src/proto/grpc/status/status.pb.h" +#include "src/proto/grpc/testing/echo_messages.pb.h" #include "test/core/util/test_config.h" - -namespace grpc { -namespace { - -TEST(ExtractTest, Success) { - google::rpc::Status expected; - expected.set_code(13); // INTERNAL - expected.set_message("I am an error message"); - testing::EchoRequest expected_details; + +namespace grpc { +namespace { + +TEST(ExtractTest, Success) { + google::rpc::Status expected; + expected.set_code(13); // INTERNAL + expected.set_message("I am an error message"); + testing::EchoRequest expected_details; expected_details.set_message(TString(100, '\0')); - expected.add_details()->PackFrom(expected_details); - - google::rpc::Status to; + expected.add_details()->PackFrom(expected_details); + + google::rpc::Status to; TString error_details = expected.SerializeAsString(); - Status from(static_cast<StatusCode>(expected.code()), expected.message(), - error_details); - EXPECT_TRUE(ExtractErrorDetails(from, &to).ok()); - EXPECT_EQ(expected.code(), to.code()); - EXPECT_EQ(expected.message(), to.message()); - EXPECT_EQ(1, to.details_size()); - testing::EchoRequest details; - to.details(0).UnpackTo(&details); - EXPECT_EQ(expected_details.message(), details.message()); -} - -TEST(ExtractTest, NullInput) { - EXPECT_EQ(StatusCode::FAILED_PRECONDITION, - ExtractErrorDetails(Status(), nullptr).error_code()); -} - -TEST(ExtractTest, Unparsable) { + Status from(static_cast<StatusCode>(expected.code()), expected.message(), + error_details); + EXPECT_TRUE(ExtractErrorDetails(from, &to).ok()); + EXPECT_EQ(expected.code(), to.code()); + EXPECT_EQ(expected.message(), to.message()); + EXPECT_EQ(1, to.details_size()); + testing::EchoRequest details; + to.details(0).UnpackTo(&details); + EXPECT_EQ(expected_details.message(), details.message()); +} + +TEST(ExtractTest, NullInput) { + EXPECT_EQ(StatusCode::FAILED_PRECONDITION, + ExtractErrorDetails(Status(), nullptr).error_code()); +} + +TEST(ExtractTest, Unparsable) { TString error_details("I am not a status object"); - Status from(StatusCode::INTERNAL, "", error_details); - google::rpc::Status to; - EXPECT_EQ(StatusCode::INVALID_ARGUMENT, - ExtractErrorDetails(from, &to).error_code()); -} - -TEST(SetTest, Success) { - google::rpc::Status expected; - expected.set_code(13); // INTERNAL - expected.set_message("I am an error message"); - testing::EchoRequest expected_details; + Status from(StatusCode::INTERNAL, "", error_details); + google::rpc::Status to; + EXPECT_EQ(StatusCode::INVALID_ARGUMENT, + ExtractErrorDetails(from, &to).error_code()); +} + +TEST(SetTest, Success) { + google::rpc::Status expected; + expected.set_code(13); // INTERNAL + expected.set_message("I am an error message"); + testing::EchoRequest expected_details; expected_details.set_message(TString(100, '\0')); - expected.add_details()->PackFrom(expected_details); - - Status to; - Status s = SetErrorDetails(expected, &to); - EXPECT_TRUE(s.ok()); - EXPECT_EQ(expected.code(), to.error_code()); - EXPECT_EQ(expected.message(), to.error_message()); - EXPECT_EQ(expected.SerializeAsString(), to.error_details()); -} - -TEST(SetTest, NullInput) { - EXPECT_EQ(StatusCode::FAILED_PRECONDITION, - SetErrorDetails(google::rpc::Status(), nullptr).error_code()); -} - -TEST(SetTest, OutOfScopeErrorCode) { - google::rpc::Status expected; - expected.set_code(17); // Out of scope (UNAUTHENTICATED is 16). - expected.set_message("I am an error message"); - testing::EchoRequest expected_details; + expected.add_details()->PackFrom(expected_details); + + Status to; + Status s = SetErrorDetails(expected, &to); + EXPECT_TRUE(s.ok()); + EXPECT_EQ(expected.code(), to.error_code()); + EXPECT_EQ(expected.message(), to.error_message()); + EXPECT_EQ(expected.SerializeAsString(), to.error_details()); +} + +TEST(SetTest, NullInput) { + EXPECT_EQ(StatusCode::FAILED_PRECONDITION, + SetErrorDetails(google::rpc::Status(), nullptr).error_code()); +} + +TEST(SetTest, OutOfScopeErrorCode) { + google::rpc::Status expected; + expected.set_code(17); // Out of scope (UNAUTHENTICATED is 16). + expected.set_message("I am an error message"); + testing::EchoRequest expected_details; expected_details.set_message(TString(100, '\0')); - expected.add_details()->PackFrom(expected_details); - - Status to; - Status s = SetErrorDetails(expected, &to); - EXPECT_TRUE(s.ok()); - EXPECT_EQ(StatusCode::UNKNOWN, to.error_code()); - EXPECT_EQ(expected.message(), to.error_message()); - EXPECT_EQ(expected.SerializeAsString(), to.error_details()); -} - -TEST(SetTest, ValidScopeErrorCode) { - for (int c = StatusCode::OK; c <= StatusCode::UNAUTHENTICATED; c++) { - google::rpc::Status expected; - expected.set_code(c); - expected.set_message("I am an error message"); - testing::EchoRequest expected_details; + expected.add_details()->PackFrom(expected_details); + + Status to; + Status s = SetErrorDetails(expected, &to); + EXPECT_TRUE(s.ok()); + EXPECT_EQ(StatusCode::UNKNOWN, to.error_code()); + EXPECT_EQ(expected.message(), to.error_message()); + EXPECT_EQ(expected.SerializeAsString(), to.error_details()); +} + +TEST(SetTest, ValidScopeErrorCode) { + for (int c = StatusCode::OK; c <= StatusCode::UNAUTHENTICATED; c++) { + google::rpc::Status expected; + expected.set_code(c); + expected.set_message("I am an error message"); + testing::EchoRequest expected_details; expected_details.set_message(TString(100, '\0')); - expected.add_details()->PackFrom(expected_details); - - Status to; - Status s = SetErrorDetails(expected, &to); - EXPECT_TRUE(s.ok()); - EXPECT_EQ(c, to.error_code()); - EXPECT_EQ(expected.message(), to.error_message()); - EXPECT_EQ(expected.SerializeAsString(), to.error_details()); - } -} - -} // namespace -} // namespace grpc - -int main(int argc, char** argv) { + expected.add_details()->PackFrom(expected_details); + + Status to; + Status s = SetErrorDetails(expected, &to); + EXPECT_TRUE(s.ok()); + EXPECT_EQ(c, to.error_code()); + EXPECT_EQ(expected.message(), to.error_message()); + EXPECT_EQ(expected.SerializeAsString(), to.error_details()); + } +} + +} // namespace +} // namespace grpc + +int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/contrib/libs/grpc/test/cpp/util/grpc_cli.cc b/contrib/libs/grpc/test/cpp/util/grpc_cli.cc index 45c6b94f84b..b816b3442b8 100644 --- a/contrib/libs/grpc/test/cpp/util/grpc_cli.cc +++ b/contrib/libs/grpc/test/cpp/util/grpc_cli.cc @@ -1,90 +1,90 @@ -/* - - * 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. - * - */ - -/* - A command line tool to talk to a grpc server. - Run `grpc_cli help` command to see its usage information. - - Example of talking to grpc interop server: - grpc_cli call localhost:50051 UnaryCall "response_size:10" \ - --protofiles=src/proto/grpc/testing/test.proto --enable_ssl=false - - Options: - 1. --protofiles, use this flag to provide proto files if the server does - does not have the reflection service. - 2. --proto_path, if your proto file is not under current working directory, - use this flag to provide a search root. It should work similar to the - counterpart in protoc. This option is valid only when protofiles is - provided. - 3. --metadata specifies metadata to be sent to the server, such as: - --metadata="MyHeaderKey1:Value1:MyHeaderKey2:Value2" - 4. --enable_ssl, whether to use tls. - 5. --use_auth, if set to true, attach a GoogleDefaultCredentials to the call - 6. --infile, input filename (defaults to stdin) - 7. --outfile, output filename (defaults to stdout) - 8. --binary_input, use the serialized request as input. The serialized - request can be generated by calling something like: - protoc --proto_path=src/proto/grpc/testing/ \ - --encode=grpc.testing.SimpleRequest \ - src/proto/grpc/testing/messages.proto \ - < input.txt > input.bin - If this is used and no proto file is provided in the argument list, the - method string has to be exact in the form of /package.service/method. - 9. --binary_output, use binary format response as output, it can - be later decoded using protoc: - protoc --proto_path=src/proto/grpc/testing/ \ - --decode=grpc.testing.SimpleResponse \ - src/proto/grpc/testing/messages.proto \ - < output.bin > output.txt +/* + + * 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. + * + */ + +/* + A command line tool to talk to a grpc server. + Run `grpc_cli help` command to see its usage information. + + Example of talking to grpc interop server: + grpc_cli call localhost:50051 UnaryCall "response_size:10" \ + --protofiles=src/proto/grpc/testing/test.proto --enable_ssl=false + + Options: + 1. --protofiles, use this flag to provide proto files if the server does + does not have the reflection service. + 2. --proto_path, if your proto file is not under current working directory, + use this flag to provide a search root. It should work similar to the + counterpart in protoc. This option is valid only when protofiles is + provided. + 3. --metadata specifies metadata to be sent to the server, such as: + --metadata="MyHeaderKey1:Value1:MyHeaderKey2:Value2" + 4. --enable_ssl, whether to use tls. + 5. --use_auth, if set to true, attach a GoogleDefaultCredentials to the call + 6. --infile, input filename (defaults to stdin) + 7. --outfile, output filename (defaults to stdout) + 8. --binary_input, use the serialized request as input. The serialized + request can be generated by calling something like: + protoc --proto_path=src/proto/grpc/testing/ \ + --encode=grpc.testing.SimpleRequest \ + src/proto/grpc/testing/messages.proto \ + < input.txt > input.bin + If this is used and no proto file is provided in the argument list, the + method string has to be exact in the form of /package.service/method. + 9. --binary_output, use binary format response as output, it can + be later decoded using protoc: + protoc --proto_path=src/proto/grpc/testing/ \ + --decode=grpc.testing.SimpleResponse \ + src/proto/grpc/testing/messages.proto \ + < output.bin > output.txt 10. --default_service_config, optional default service config to use on the channel. Note that this may be ignored if the name resolver returns a service config. 11. --display_peer_address, on CallMethod commands, log the peer socket address of the connection that each RPC is made on to stderr. -*/ - -#include <fstream> -#include <functional> -#include <iostream> - -#include <gflags/gflags.h> -#include <grpcpp/support/config.h> -#include "test/cpp/util/cli_credentials.h" -#include "test/cpp/util/grpc_tool.h" -#include "test/cpp/util/test_config.h" - -DEFINE_string(outfile, "", "Output file (default is stdout)"); - +*/ + +#include <fstream> +#include <functional> +#include <iostream> + +#include <gflags/gflags.h> +#include <grpcpp/support/config.h> +#include "test/cpp/util/cli_credentials.h" +#include "test/cpp/util/grpc_tool.h" +#include "test/cpp/util/test_config.h" + +DEFINE_string(outfile, "", "Output file (default is stdout)"); + static bool SimplePrint(const TString& outfile, const TString& output) { - if (outfile.empty()) { + if (outfile.empty()) { std::cout << output << std::flush; - } else { - std::ofstream output_file(outfile, std::ios::app | std::ios::binary); + } else { + std::ofstream output_file(outfile, std::ios::app | std::ios::binary); output_file << output << std::flush; - output_file.close(); - } - return true; -} - -int main(int argc, char** argv) { - grpc::testing::InitTest(&argc, &argv, true); - - return grpc::testing::GrpcToolMainLib( - argc, (const char**)argv, grpc::testing::CliCredentials(), + output_file.close(); + } + return true; +} + +int main(int argc, char** argv) { + grpc::testing::InitTest(&argc, &argv, true); + + return grpc::testing::GrpcToolMainLib( + argc, (const char**)argv, grpc::testing::CliCredentials(), std::bind(SimplePrint, TString(FLAGS_outfile.c_str()), std::placeholders::_1)); -} +} diff --git a/contrib/libs/grpc/test/cpp/util/grpc_tool.cc b/contrib/libs/grpc/test/cpp/util/grpc_tool.cc index 30f3024e25b..6897d662207 100644 --- a/contrib/libs/grpc/test/cpp/util/grpc_tool.cc +++ b/contrib/libs/grpc/test/cpp/util/grpc_tool.cc @@ -1,32 +1,32 @@ -/* - * - * Copyright 2016 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 "test/cpp/util/grpc_tool.h" - -#include <gflags/gflags.h> -#include <grpc/grpc.h> -#include <grpc/support/port_platform.h> -#include <grpcpp/channel.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/grpcpp.h> -#include <grpcpp/security/credentials.h> -#include <grpcpp/support/string_ref.h> - +/* + * + * Copyright 2016 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 "test/cpp/util/grpc_tool.h" + +#include <gflags/gflags.h> +#include <grpc/grpc.h> +#include <grpc/support/port_platform.h> +#include <grpcpp/channel.h> +#include <grpcpp/create_channel.h> +#include <grpcpp/grpcpp.h> +#include <grpcpp/security/credentials.h> +#include <grpcpp/support/string_ref.h> + #include <cstdio> #include <fstream> #include <iostream> @@ -35,28 +35,28 @@ #include <util/generic/string.h> #include <thread> -#include "test/cpp/util/cli_call.h" -#include "test/cpp/util/proto_file_parser.h" -#include "test/cpp/util/proto_reflection_descriptor_database.h" -#include "test/cpp/util/service_describer.h" - -#if GPR_WINDOWS -#include <io.h> -#else -#include <unistd.h> -#endif - -namespace grpc { -namespace testing { - -DEFINE_bool(l, false, "Use a long listing format"); -DEFINE_bool(remotedb, true, "Use server types to parse and format messages"); -DEFINE_string(metadata, "", - "Metadata to send to server, in the form of key1:val1:key2:val2"); -DEFINE_string(proto_path, ".", "Path to look for the proto file."); -DEFINE_string(protofiles, "", "Name of the proto file."); -DEFINE_bool(binary_input, false, "Input in binary format"); -DEFINE_bool(binary_output, false, "Output in binary format"); +#include "test/cpp/util/cli_call.h" +#include "test/cpp/util/proto_file_parser.h" +#include "test/cpp/util/proto_reflection_descriptor_database.h" +#include "test/cpp/util/service_describer.h" + +#if GPR_WINDOWS +#include <io.h> +#else +#include <unistd.h> +#endif + +namespace grpc { +namespace testing { + +DEFINE_bool(l, false, "Use a long listing format"); +DEFINE_bool(remotedb, true, "Use server types to parse and format messages"); +DEFINE_string(metadata, "", + "Metadata to send to server, in the form of key1:val1:key2:val2"); +DEFINE_string(proto_path, ".", "Path to look for the proto file."); +DEFINE_string(protofiles, "", "Name of the proto file."); +DEFINE_bool(binary_input, false, "Input in binary format"); +DEFINE_bool(binary_output, false, "Output in binary format"); DEFINE_string( default_service_config, "", "Default service config to use on the channel, if non-empty. Note " @@ -68,161 +68,161 @@ DEFINE_bool( "on to stderr."); DEFINE_bool(json_input, false, "Input in json format"); DEFINE_bool(json_output, false, "Output in json format"); -DEFINE_string(infile, "", "Input file (default is stdin)"); -DEFINE_bool(batch, false, - "Input contains multiple requests. Please do not use this to send " - "more than a few RPCs. gRPC CLI has very different performance " - "characteristics compared with normal RPC calls which make it " - "unsuitable for loadtesting or significant production traffic."); +DEFINE_string(infile, "", "Input file (default is stdin)"); +DEFINE_bool(batch, false, + "Input contains multiple requests. Please do not use this to send " + "more than a few RPCs. gRPC CLI has very different performance " + "characteristics compared with normal RPC calls which make it " + "unsuitable for loadtesting or significant production traffic."); DEFINE_double(timeout, -1, "Specify timeout in seconds, used to set the deadline for all " "RPCs. The default value of -1 means no deadline has been set."); - -namespace { - -class GrpcTool { - public: - explicit GrpcTool(); - virtual ~GrpcTool() {} - - bool Help(int argc, const char** argv, const CliCredentials& cred, - GrpcToolOutputCallback callback); - bool CallMethod(int argc, const char** argv, const CliCredentials& cred, - GrpcToolOutputCallback callback); - bool ListServices(int argc, const char** argv, const CliCredentials& cred, - GrpcToolOutputCallback callback); - bool PrintType(int argc, const char** argv, const CliCredentials& cred, - GrpcToolOutputCallback callback); - // TODO(zyc): implement the following methods - // bool ListServices(int argc, const char** argv, GrpcToolOutputCallback - // callback); - // bool PrintTypeId(int argc, const char** argv, GrpcToolOutputCallback - // callback); - bool ParseMessage(int argc, const char** argv, const CliCredentials& cred, - GrpcToolOutputCallback callback); - bool ToText(int argc, const char** argv, const CliCredentials& cred, - GrpcToolOutputCallback callback); + +namespace { + +class GrpcTool { + public: + explicit GrpcTool(); + virtual ~GrpcTool() {} + + bool Help(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback); + bool CallMethod(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback); + bool ListServices(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback); + bool PrintType(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback); + // TODO(zyc): implement the following methods + // bool ListServices(int argc, const char** argv, GrpcToolOutputCallback + // callback); + // bool PrintTypeId(int argc, const char** argv, GrpcToolOutputCallback + // callback); + bool ParseMessage(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback); + bool ToText(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback); bool ToJson(int argc, const char** argv, const CliCredentials& cred, GrpcToolOutputCallback callback); - bool ToBinary(int argc, const char** argv, const CliCredentials& cred, - GrpcToolOutputCallback callback); - - void SetPrintCommandMode(int exit_status) { - print_command_usage_ = true; - usage_exit_status_ = exit_status; - } - - private: + bool ToBinary(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback); + + void SetPrintCommandMode(int exit_status) { + print_command_usage_ = true; + usage_exit_status_ = exit_status; + } + + private: void CommandUsage(const TString& usage) const; - bool print_command_usage_; - int usage_exit_status_; + bool print_command_usage_; + int usage_exit_status_; const TString cred_usage_; -}; - -template <typename T> -std::function<bool(GrpcTool*, int, const char**, const CliCredentials&, - GrpcToolOutputCallback)> -BindWith5Args(T&& func) { - return std::bind(std::forward<T>(func), std::placeholders::_1, - std::placeholders::_2, std::placeholders::_3, - std::placeholders::_4, std::placeholders::_5); -} - -template <typename T> -size_t ArraySize(T& a) { - return ((sizeof(a) / sizeof(*(a))) / - static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))); -} - -void ParseMetadataFlag( +}; + +template <typename T> +std::function<bool(GrpcTool*, int, const char**, const CliCredentials&, + GrpcToolOutputCallback)> +BindWith5Args(T&& func) { + return std::bind(std::forward<T>(func), std::placeholders::_1, + std::placeholders::_2, std::placeholders::_3, + std::placeholders::_4, std::placeholders::_5); +} + +template <typename T> +size_t ArraySize(T& a) { + return ((sizeof(a) / sizeof(*(a))) / + static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))); +} + +void ParseMetadataFlag( std::multimap<TString, TString>* client_metadata) { - if (FLAGS_metadata.empty()) { - return; - } + if (FLAGS_metadata.empty()) { + return; + } std::vector<TString> fields; - const char delim = ':'; - const char escape = '\\'; - size_t cur = -1; - std::stringstream ss; - while (++cur < FLAGS_metadata.length()) { - switch (FLAGS_metadata.at(cur)) { - case escape: - if (cur < FLAGS_metadata.length() - 1) { - char c = FLAGS_metadata.at(++cur); - if (c == delim || c == escape) { - ss << c; - continue; - } - } - fprintf(stderr, "Failed to parse metadata flag.\n"); - exit(1); - case delim: - fields.push_back(ss.str()); - ss.str(""); - ss.clear(); - break; - default: - ss << FLAGS_metadata.at(cur); - } - } - fields.push_back(ss.str()); - if (fields.size() % 2) { - fprintf(stderr, "Failed to parse metadata flag.\n"); - exit(1); - } - for (size_t i = 0; i < fields.size(); i += 2) { - client_metadata->insert( + const char delim = ':'; + const char escape = '\\'; + size_t cur = -1; + std::stringstream ss; + while (++cur < FLAGS_metadata.length()) { + switch (FLAGS_metadata.at(cur)) { + case escape: + if (cur < FLAGS_metadata.length() - 1) { + char c = FLAGS_metadata.at(++cur); + if (c == delim || c == escape) { + ss << c; + continue; + } + } + fprintf(stderr, "Failed to parse metadata flag.\n"); + exit(1); + case delim: + fields.push_back(ss.str()); + ss.str(""); + ss.clear(); + break; + default: + ss << FLAGS_metadata.at(cur); + } + } + fields.push_back(ss.str()); + if (fields.size() % 2) { + fprintf(stderr, "Failed to parse metadata flag.\n"); + exit(1); + } + for (size_t i = 0; i < fields.size(); i += 2) { + client_metadata->insert( std::pair<TString, TString>(fields[i], fields[i + 1])); - } -} - -template <typename T> + } +} + +template <typename T> void PrintMetadata(const T& m, const TString& message) { - if (m.empty()) { - return; - } - fprintf(stderr, "%s\n", message.c_str()); + if (m.empty()) { + return; + } + fprintf(stderr, "%s\n", message.c_str()); TString pair; - for (typename T::const_iterator iter = m.begin(); iter != m.end(); ++iter) { - pair.clear(); - pair.append(iter->first.data(), iter->first.size()); - pair.append(" : "); - pair.append(iter->second.data(), iter->second.size()); - fprintf(stderr, "%s\n", pair.c_str()); - } -} - + for (typename T::const_iterator iter = m.begin(); iter != m.end(); ++iter) { + pair.clear(); + pair.append(iter->first.data(), iter->first.size()); + pair.append(" : "); + pair.append(iter->second.data(), iter->second.size()); + fprintf(stderr, "%s\n", pair.c_str()); + } +} + void ReadResponse(CliCall* call, const TString& method_name, - GrpcToolOutputCallback callback, ProtoFileParser* parser, - gpr_mu* parser_mu, bool print_mode) { + GrpcToolOutputCallback callback, ProtoFileParser* parser, + gpr_mu* parser_mu, bool print_mode) { TString serialized_response_proto; - std::multimap<grpc::string_ref, grpc::string_ref> server_initial_metadata; - - for (bool receive_initial_metadata = true; call->ReadAndMaybeNotifyWrite( - &serialized_response_proto, - receive_initial_metadata ? &server_initial_metadata : nullptr); - receive_initial_metadata = false) { - fprintf(stderr, "got response.\n"); - if (!FLAGS_binary_output) { - gpr_mu_lock(parser_mu); + std::multimap<grpc::string_ref, grpc::string_ref> server_initial_metadata; + + for (bool receive_initial_metadata = true; call->ReadAndMaybeNotifyWrite( + &serialized_response_proto, + receive_initial_metadata ? &server_initial_metadata : nullptr); + receive_initial_metadata = false) { + fprintf(stderr, "got response.\n"); + if (!FLAGS_binary_output) { + gpr_mu_lock(parser_mu); serialized_response_proto = parser->GetFormattedStringFromMethod( method_name, serialized_response_proto, false /* is_request */, FLAGS_json_output); - if (parser->HasError() && print_mode) { - fprintf(stderr, "Failed to parse response.\n"); - } - gpr_mu_unlock(parser_mu); - } - if (receive_initial_metadata) { - PrintMetadata(server_initial_metadata, - "Received initial metadata from server:"); - } - if (!callback(serialized_response_proto) && print_mode) { - fprintf(stderr, "Failed to output response.\n"); - } - } -} - + if (parser->HasError() && print_mode) { + fprintf(stderr, "Failed to parse response.\n"); + } + gpr_mu_unlock(parser_mu); + } + if (receive_initial_metadata) { + PrintMetadata(server_initial_metadata, + "Received initial metadata from server:"); + } + if (!callback(serialized_response_proto) && print_mode) { + fprintf(stderr, "Failed to output response.\n"); + } + } +} + std::shared_ptr<grpc::Channel> CreateCliChannel( const TString& server_address, const CliCredentials& cred) { grpc::ChannelArguments args; @@ -237,282 +237,282 @@ std::shared_ptr<grpc::Channel> CreateCliChannel( args); } -struct Command { - const char* command; - std::function<bool(GrpcTool*, int, const char**, const CliCredentials&, - GrpcToolOutputCallback)> - function; - int min_args; - int max_args; -}; - -const Command ops[] = { - {"help", BindWith5Args(&GrpcTool::Help), 0, INT_MAX}, - {"ls", BindWith5Args(&GrpcTool::ListServices), 1, 3}, - {"list", BindWith5Args(&GrpcTool::ListServices), 1, 3}, - {"call", BindWith5Args(&GrpcTool::CallMethod), 2, 3}, - {"type", BindWith5Args(&GrpcTool::PrintType), 2, 2}, - {"parse", BindWith5Args(&GrpcTool::ParseMessage), 2, 3}, - {"totext", BindWith5Args(&GrpcTool::ToText), 2, 3}, - {"tobinary", BindWith5Args(&GrpcTool::ToBinary), 2, 3}, +struct Command { + const char* command; + std::function<bool(GrpcTool*, int, const char**, const CliCredentials&, + GrpcToolOutputCallback)> + function; + int min_args; + int max_args; +}; + +const Command ops[] = { + {"help", BindWith5Args(&GrpcTool::Help), 0, INT_MAX}, + {"ls", BindWith5Args(&GrpcTool::ListServices), 1, 3}, + {"list", BindWith5Args(&GrpcTool::ListServices), 1, 3}, + {"call", BindWith5Args(&GrpcTool::CallMethod), 2, 3}, + {"type", BindWith5Args(&GrpcTool::PrintType), 2, 2}, + {"parse", BindWith5Args(&GrpcTool::ParseMessage), 2, 3}, + {"totext", BindWith5Args(&GrpcTool::ToText), 2, 3}, + {"tobinary", BindWith5Args(&GrpcTool::ToBinary), 2, 3}, {"tojson", BindWith5Args(&GrpcTool::ToJson), 2, 3}, -}; - +}; + void Usage(const TString& msg) { - fprintf( - stderr, - "%s\n" - " grpc_cli ls ... ; List services\n" - " grpc_cli call ... ; Call method\n" - " grpc_cli type ... ; Print type\n" - " grpc_cli parse ... ; Parse message\n" - " grpc_cli totext ... ; Convert binary message to text\n" + fprintf( + stderr, + "%s\n" + " grpc_cli ls ... ; List services\n" + " grpc_cli call ... ; Call method\n" + " grpc_cli type ... ; Print type\n" + " grpc_cli parse ... ; Parse message\n" + " grpc_cli totext ... ; Convert binary message to text\n" " grpc_cli tojson ... ; Convert binary message to json\n" - " grpc_cli tobinary ... ; Convert text message to binary\n" - " grpc_cli help ... ; Print this message, or per-command usage\n" - "\n", - msg.c_str()); - - exit(1); -} - + " grpc_cli tobinary ... ; Convert text message to binary\n" + " grpc_cli help ... ; Print this message, or per-command usage\n" + "\n", + msg.c_str()); + + exit(1); +} + const Command* FindCommand(const TString& name) { - for (int i = 0; i < (int)ArraySize(ops); i++) { - if (name == ops[i].command) { - return &ops[i]; - } - } - return nullptr; -} -} // namespace - -int GrpcToolMainLib(int argc, const char** argv, const CliCredentials& cred, - GrpcToolOutputCallback callback) { - if (argc < 2) { - Usage("No command specified"); - } - + for (int i = 0; i < (int)ArraySize(ops); i++) { + if (name == ops[i].command) { + return &ops[i]; + } + } + return nullptr; +} +} // namespace + +int GrpcToolMainLib(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback) { + if (argc < 2) { + Usage("No command specified"); + } + TString command = argv[1]; - argc -= 2; - argv += 2; - - const Command* cmd = FindCommand(command); - if (cmd != nullptr) { - GrpcTool grpc_tool; - if (argc < cmd->min_args || argc > cmd->max_args) { - // Force the command to print its usage message - fprintf(stderr, "\nWrong number of arguments for %s\n", command.c_str()); - grpc_tool.SetPrintCommandMode(1); - return cmd->function(&grpc_tool, -1, nullptr, cred, callback); - } - const bool ok = cmd->function(&grpc_tool, argc, argv, cred, callback); - return ok ? 0 : 1; - } else { + argc -= 2; + argv += 2; + + const Command* cmd = FindCommand(command); + if (cmd != nullptr) { + GrpcTool grpc_tool; + if (argc < cmd->min_args || argc > cmd->max_args) { + // Force the command to print its usage message + fprintf(stderr, "\nWrong number of arguments for %s\n", command.c_str()); + grpc_tool.SetPrintCommandMode(1); + return cmd->function(&grpc_tool, -1, nullptr, cred, callback); + } + const bool ok = cmd->function(&grpc_tool, argc, argv, cred, callback); + return ok ? 0 : 1; + } else { Usage("Invalid command '" + TString(command.c_str()) + "'"); - } - return 1; -} - -GrpcTool::GrpcTool() : print_command_usage_(false), usage_exit_status_(0) {} - + } + return 1; +} + +GrpcTool::GrpcTool() : print_command_usage_(false), usage_exit_status_(0) {} + void GrpcTool::CommandUsage(const TString& usage) const { - if (print_command_usage_) { - fprintf(stderr, "\n%s%s\n", usage.c_str(), - (usage.empty() || usage[usage.size() - 1] != '\n') ? "\n" : ""); - exit(usage_exit_status_); - } -} - -bool GrpcTool::Help(int argc, const char** argv, const CliCredentials& cred, - GrpcToolOutputCallback callback) { - CommandUsage( - "Print help\n" - " grpc_cli help [subcommand]\n"); - - if (argc == 0) { - Usage(""); - } else { - const Command* cmd = FindCommand(argv[0]); - if (cmd == nullptr) { + if (print_command_usage_) { + fprintf(stderr, "\n%s%s\n", usage.c_str(), + (usage.empty() || usage[usage.size() - 1] != '\n') ? "\n" : ""); + exit(usage_exit_status_); + } +} + +bool GrpcTool::Help(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback) { + CommandUsage( + "Print help\n" + " grpc_cli help [subcommand]\n"); + + if (argc == 0) { + Usage(""); + } else { + const Command* cmd = FindCommand(argv[0]); + if (cmd == nullptr) { Usage("Unknown command '" + TString(argv[0]) + "'"); - } - SetPrintCommandMode(0); - cmd->function(this, -1, nullptr, cred, callback); - } - return true; -} - -bool GrpcTool::ListServices(int argc, const char** argv, - const CliCredentials& cred, - GrpcToolOutputCallback callback) { - CommandUsage( - "List services\n" - " grpc_cli ls <address> [<service>[/<method>]]\n" - " <address> ; host:port\n" - " <service> ; Exported service name\n" - " <method> ; Method name\n" - " --l ; Use a long listing format\n" - " --outfile ; Output filename (defaults to stdout)\n" + - cred.GetCredentialUsage()); - + } + SetPrintCommandMode(0); + cmd->function(this, -1, nullptr, cred, callback); + } + return true; +} + +bool GrpcTool::ListServices(int argc, const char** argv, + const CliCredentials& cred, + GrpcToolOutputCallback callback) { + CommandUsage( + "List services\n" + " grpc_cli ls <address> [<service>[/<method>]]\n" + " <address> ; host:port\n" + " <service> ; Exported service name\n" + " <method> ; Method name\n" + " --l ; Use a long listing format\n" + " --outfile ; Output filename (defaults to stdout)\n" + + cred.GetCredentialUsage()); + TString server_address(argv[0]); - std::shared_ptr<grpc::Channel> channel = + std::shared_ptr<grpc::Channel> channel = CreateCliChannel(server_address, cred); - grpc::ProtoReflectionDescriptorDatabase desc_db(channel); - grpc::protobuf::DescriptorPool desc_pool(&desc_db); - + grpc::ProtoReflectionDescriptorDatabase desc_db(channel); + grpc::protobuf::DescriptorPool desc_pool(&desc_db); + std::vector<TString> service_list; - if (!desc_db.GetServices(&service_list)) { - fprintf(stderr, "Received an error when querying services endpoint.\n"); - return false; - } - - // If no service is specified, dump the list of services. + if (!desc_db.GetServices(&service_list)) { + fprintf(stderr, "Received an error when querying services endpoint.\n"); + return false; + } + + // If no service is specified, dump the list of services. TString output; - if (argc < 2) { - // List all services, if --l is passed, then include full description, - // otherwise include a summarized list only. - if (FLAGS_l) { - output = DescribeServiceList(service_list, desc_pool); - } else { - for (auto it = service_list.begin(); it != service_list.end(); it++) { - auto const& service = *it; - output.append(service); - output.append("\n"); - } - } - } else { + if (argc < 2) { + // List all services, if --l is passed, then include full description, + // otherwise include a summarized list only. + if (FLAGS_l) { + output = DescribeServiceList(service_list, desc_pool); + } else { + for (auto it = service_list.begin(); it != service_list.end(); it++) { + auto const& service = *it; + output.append(service); + output.append("\n"); + } + } + } else { std::string service_name; std::string method_name; - std::stringstream ss(argv[1]); - - // Remove leading slashes. - while (ss.peek() == '/') { - ss.get(); - } - - // Parse service and method names. Support the following patterns: - // Service - // Service Method - // Service.Method - // Service/Method - if (argc == 3) { - std::getline(ss, service_name, '/'); - method_name = argv[2]; - } else { - if (std::getline(ss, service_name, '/')) { - std::getline(ss, method_name); - } - } - - const grpc::protobuf::ServiceDescriptor* service = - desc_pool.FindServiceByName(google::protobuf::string(service_name)); - if (service != nullptr) { - if (method_name.empty()) { - output = FLAGS_l ? DescribeService(service) : SummarizeService(service); - } else { - method_name.insert(0, "."); - method_name.insert(0, service_name); - const grpc::protobuf::MethodDescriptor* method = - desc_pool.FindMethodByName(google::protobuf::string(method_name)); - if (method != nullptr) { - output = FLAGS_l ? DescribeMethod(method) : SummarizeMethod(method); - } else { - fprintf(stderr, "Method %s not found in service %s.\n", - method_name.c_str(), service_name.c_str()); - return false; - } - } - } else { - if (!method_name.empty()) { - fprintf(stderr, "Service %s not found.\n", service_name.c_str()); - return false; - } else { - const grpc::protobuf::MethodDescriptor* method = - desc_pool.FindMethodByName(google::protobuf::string(service_name)); - if (method != nullptr) { - output = FLAGS_l ? DescribeMethod(method) : SummarizeMethod(method); - } else { - fprintf(stderr, "Service or method %s not found.\n", - service_name.c_str()); - return false; - } - } - } - } - return callback(output); -} - + std::stringstream ss(argv[1]); + + // Remove leading slashes. + while (ss.peek() == '/') { + ss.get(); + } + + // Parse service and method names. Support the following patterns: + // Service + // Service Method + // Service.Method + // Service/Method + if (argc == 3) { + std::getline(ss, service_name, '/'); + method_name = argv[2]; + } else { + if (std::getline(ss, service_name, '/')) { + std::getline(ss, method_name); + } + } + + const grpc::protobuf::ServiceDescriptor* service = + desc_pool.FindServiceByName(google::protobuf::string(service_name)); + if (service != nullptr) { + if (method_name.empty()) { + output = FLAGS_l ? DescribeService(service) : SummarizeService(service); + } else { + method_name.insert(0, "."); + method_name.insert(0, service_name); + const grpc::protobuf::MethodDescriptor* method = + desc_pool.FindMethodByName(google::protobuf::string(method_name)); + if (method != nullptr) { + output = FLAGS_l ? DescribeMethod(method) : SummarizeMethod(method); + } else { + fprintf(stderr, "Method %s not found in service %s.\n", + method_name.c_str(), service_name.c_str()); + return false; + } + } + } else { + if (!method_name.empty()) { + fprintf(stderr, "Service %s not found.\n", service_name.c_str()); + return false; + } else { + const grpc::protobuf::MethodDescriptor* method = + desc_pool.FindMethodByName(google::protobuf::string(service_name)); + if (method != nullptr) { + output = FLAGS_l ? DescribeMethod(method) : SummarizeMethod(method); + } else { + fprintf(stderr, "Service or method %s not found.\n", + service_name.c_str()); + return false; + } + } + } + } + return callback(output); +} + bool GrpcTool::PrintType(int /*argc*/, const char** argv, - const CliCredentials& cred, - GrpcToolOutputCallback callback) { - CommandUsage( - "Print type\n" - " grpc_cli type <address> <type>\n" - " <address> ; host:port\n" - " <type> ; Protocol buffer type name\n" + - cred.GetCredentialUsage()); - + const CliCredentials& cred, + GrpcToolOutputCallback callback) { + CommandUsage( + "Print type\n" + " grpc_cli type <address> <type>\n" + " <address> ; host:port\n" + " <type> ; Protocol buffer type name\n" + + cred.GetCredentialUsage()); + TString server_address(argv[0]); - std::shared_ptr<grpc::Channel> channel = + std::shared_ptr<grpc::Channel> channel = CreateCliChannel(server_address, cred); - grpc::ProtoReflectionDescriptorDatabase desc_db(channel); - grpc::protobuf::DescriptorPool desc_pool(&desc_db); - + grpc::ProtoReflectionDescriptorDatabase desc_db(channel); + grpc::protobuf::DescriptorPool desc_pool(&desc_db); + TString output; - const grpc::protobuf::Descriptor* descriptor = - desc_pool.FindMessageTypeByName(argv[1]); - if (descriptor != nullptr) { - output = descriptor->DebugString(); - } else { - fprintf(stderr, "Type %s not found.\n", argv[1]); - return false; - } - return callback(output); -} - -bool GrpcTool::CallMethod(int argc, const char** argv, - const CliCredentials& cred, - GrpcToolOutputCallback callback) { - CommandUsage( - "Call method\n" - " grpc_cli call <address> <service>[.<method>] <request>\n" - " <address> ; host:port\n" - " <service> ; Exported service name\n" - " <method> ; Method name\n" - " <request> ; Text protobuffer (overrides infile)\n" - " --protofiles ; Comma separated proto files used as a" - " fallback when parsing request/response\n" - " --proto_path ; The search path of proto files, valid" - " only when --protofiles is given\n" + const grpc::protobuf::Descriptor* descriptor = + desc_pool.FindMessageTypeByName(argv[1]); + if (descriptor != nullptr) { + output = descriptor->DebugString(); + } else { + fprintf(stderr, "Type %s not found.\n", argv[1]); + return false; + } + return callback(output); +} + +bool GrpcTool::CallMethod(int argc, const char** argv, + const CliCredentials& cred, + GrpcToolOutputCallback callback) { + CommandUsage( + "Call method\n" + " grpc_cli call <address> <service>[.<method>] <request>\n" + " <address> ; host:port\n" + " <service> ; Exported service name\n" + " <method> ; Method name\n" + " <request> ; Text protobuffer (overrides infile)\n" + " --protofiles ; Comma separated proto files used as a" + " fallback when parsing request/response\n" + " --proto_path ; The search path of proto files, valid" + " only when --protofiles is given\n" " --noremotedb ; Don't attempt to use reflection service" " at all\n" - " --metadata ; The metadata to be sent to the server\n" - " --infile ; Input filename (defaults to stdin)\n" - " --outfile ; Output filename (defaults to stdout)\n" - " --binary_input ; Input in binary format\n" + " --metadata ; The metadata to be sent to the server\n" + " --infile ; Input filename (defaults to stdin)\n" + " --outfile ; Output filename (defaults to stdout)\n" + " --binary_input ; Input in binary format\n" " --binary_output ; Output in binary format\n" " --json_input ; Input in json format\n" " --json_output ; Output in json format\n" " --timeout ; Specify timeout (in seconds), used to " "set the deadline for RPCs. The default value of -1 means no " "deadline has been set.\n" + - cred.GetCredentialUsage()); - - std::stringstream output_ss; + cred.GetCredentialUsage()); + + std::stringstream output_ss; TString request_text; TString server_address(argv[0]); TString method_name(argv[1]); TString formatted_method_name; - std::unique_ptr<ProtoFileParser> parser; + std::unique_ptr<ProtoFileParser> parser; TString serialized_request_proto; CliArgs cli_args; cli_args.timeout = FLAGS_timeout; - bool print_mode = false; - - std::shared_ptr<grpc::Channel> channel = + bool print_mode = false; + + std::shared_ptr<grpc::Channel> channel = CreateCliChannel(server_address, cred); - + if (!FLAGS_binary_input || !FLAGS_binary_output) { parser.reset( new grpc::testing::ProtoFileParser(FLAGS_remotedb ? channel : nullptr, @@ -524,167 +524,167 @@ bool GrpcTool::CallMethod(int argc, const char** argv, return false; } } - - if (FLAGS_binary_input) { - formatted_method_name = method_name; - } else { - formatted_method_name = parser->GetFormattedMethodName(method_name); + + if (FLAGS_binary_input) { + formatted_method_name = method_name; + } else { + formatted_method_name = parser->GetFormattedMethodName(method_name); if (parser->HasError()) { fprintf(stderr, "Failed to find method %s in proto files.\n", method_name.c_str()); } - } - - if (argc == 3) { - request_text = argv[2]; - } - - if (parser->IsStreaming(method_name, true /* is_request */)) { - std::istream* input_stream; - std::ifstream input_file; - - if (FLAGS_batch) { - fprintf(stderr, "Batch mode for streaming RPC is not supported.\n"); - return false; - } - + } + + if (argc == 3) { + request_text = argv[2]; + } + + if (parser->IsStreaming(method_name, true /* is_request */)) { + std::istream* input_stream; + std::ifstream input_file; + + if (FLAGS_batch) { + fprintf(stderr, "Batch mode for streaming RPC is not supported.\n"); + return false; + } + std::multimap<TString, TString> client_metadata; - ParseMetadataFlag(&client_metadata); - PrintMetadata(client_metadata, "Sending client initial metadata:"); - + ParseMetadataFlag(&client_metadata); + PrintMetadata(client_metadata, "Sending client initial metadata:"); + CliCall call(channel, formatted_method_name, client_metadata, cli_args); if (FLAGS_display_peer_address) { fprintf(stderr, "New call for method_name:%s has peer address:|%s|\n", formatted_method_name.c_str(), call.peer().c_str()); } - - if (FLAGS_infile.empty()) { - if (isatty(fileno(stdin))) { - print_mode = true; - fprintf(stderr, "reading streaming request message from stdin...\n"); - } - input_stream = &std::cin; - } else { - input_file.open(FLAGS_infile, std::ios::in | std::ios::binary); - input_stream = &input_file; - } - - gpr_mu parser_mu; - gpr_mu_init(&parser_mu); - std::thread read_thread(ReadResponse, &call, method_name, callback, - parser.get(), &parser_mu, print_mode); - - std::stringstream request_ss; + + if (FLAGS_infile.empty()) { + if (isatty(fileno(stdin))) { + print_mode = true; + fprintf(stderr, "reading streaming request message from stdin...\n"); + } + input_stream = &std::cin; + } else { + input_file.open(FLAGS_infile, std::ios::in | std::ios::binary); + input_stream = &input_file; + } + + gpr_mu parser_mu; + gpr_mu_init(&parser_mu); + std::thread read_thread(ReadResponse, &call, method_name, callback, + parser.get(), &parser_mu, print_mode); + + std::stringstream request_ss; std::string line; - while (!request_text.empty() || - (!input_stream->eof() && getline(*input_stream, line))) { - if (!request_text.empty()) { - if (FLAGS_binary_input) { - serialized_request_proto = request_text; - request_text.clear(); - } else { - gpr_mu_lock(&parser_mu); - serialized_request_proto = parser->GetSerializedProtoFromMethod( + while (!request_text.empty() || + (!input_stream->eof() && getline(*input_stream, line))) { + if (!request_text.empty()) { + if (FLAGS_binary_input) { + serialized_request_proto = request_text; + request_text.clear(); + } else { + gpr_mu_lock(&parser_mu); + serialized_request_proto = parser->GetSerializedProtoFromMethod( method_name, request_text, true /* is_request */, FLAGS_json_input); - request_text.clear(); - if (parser->HasError()) { - if (print_mode) { - fprintf(stderr, "Failed to parse request.\n"); - } - gpr_mu_unlock(&parser_mu); - continue; - } - gpr_mu_unlock(&parser_mu); - } - - call.WriteAndWait(serialized_request_proto); - if (print_mode) { - fprintf(stderr, "Request sent.\n"); - } - } else { - if (line.length() == 0) { - request_text = request_ss.str(); + request_text.clear(); + if (parser->HasError()) { + if (print_mode) { + fprintf(stderr, "Failed to parse request.\n"); + } + gpr_mu_unlock(&parser_mu); + continue; + } + gpr_mu_unlock(&parser_mu); + } + + call.WriteAndWait(serialized_request_proto); + if (print_mode) { + fprintf(stderr, "Request sent.\n"); + } + } else { + if (line.length() == 0) { + request_text = request_ss.str(); request_ss.str(TString()); - request_ss.clear(); - } else { - request_ss << line << ' '; - } - } - } - if (input_file.is_open()) { - input_file.close(); - } - - call.WritesDoneAndWait(); - read_thread.join(); + request_ss.clear(); + } else { + request_ss << line << ' '; + } + } + } + if (input_file.is_open()) { + input_file.close(); + } + + call.WritesDoneAndWait(); + read_thread.join(); gpr_mu_destroy(&parser_mu); - - std::multimap<grpc::string_ref, grpc::string_ref> server_trailing_metadata; - Status status = call.Finish(&server_trailing_metadata); - PrintMetadata(server_trailing_metadata, - "Received trailing metadata from server:"); - - if (status.ok()) { - fprintf(stderr, "Stream RPC succeeded with OK status\n"); - return true; - } else { - fprintf(stderr, "Rpc failed with status code %d, error message: %s\n", - status.error_code(), status.error_message().c_str()); - return false; - } - - } else { // parser->IsStreaming(method_name, true /* is_request */) - if (FLAGS_batch) { - if (parser->IsStreaming(method_name, false /* is_request */)) { - fprintf(stderr, "Batch mode for streaming RPC is not supported.\n"); - return false; - } - - std::istream* input_stream; - std::ifstream input_file; - - if (FLAGS_infile.empty()) { - if (isatty(fileno(stdin))) { - print_mode = true; - fprintf(stderr, "reading request messages from stdin...\n"); - } - input_stream = &std::cin; - } else { - input_file.open(FLAGS_infile, std::ios::in | std::ios::binary); - input_stream = &input_file; - } - + + std::multimap<grpc::string_ref, grpc::string_ref> server_trailing_metadata; + Status status = call.Finish(&server_trailing_metadata); + PrintMetadata(server_trailing_metadata, + "Received trailing metadata from server:"); + + if (status.ok()) { + fprintf(stderr, "Stream RPC succeeded with OK status\n"); + return true; + } else { + fprintf(stderr, "Rpc failed with status code %d, error message: %s\n", + status.error_code(), status.error_message().c_str()); + return false; + } + + } else { // parser->IsStreaming(method_name, true /* is_request */) + if (FLAGS_batch) { + if (parser->IsStreaming(method_name, false /* is_request */)) { + fprintf(stderr, "Batch mode for streaming RPC is not supported.\n"); + return false; + } + + std::istream* input_stream; + std::ifstream input_file; + + if (FLAGS_infile.empty()) { + if (isatty(fileno(stdin))) { + print_mode = true; + fprintf(stderr, "reading request messages from stdin...\n"); + } + input_stream = &std::cin; + } else { + input_file.open(FLAGS_infile, std::ios::in | std::ios::binary); + input_stream = &input_file; + } + std::multimap<TString, TString> client_metadata; - ParseMetadataFlag(&client_metadata); - if (print_mode) { - PrintMetadata(client_metadata, "Sending client initial metadata:"); - } - - std::stringstream request_ss; + ParseMetadataFlag(&client_metadata); + if (print_mode) { + PrintMetadata(client_metadata, "Sending client initial metadata:"); + } + + std::stringstream request_ss; std::string line; - while (!request_text.empty() || - (!input_stream->eof() && getline(*input_stream, line))) { - if (!request_text.empty()) { - if (FLAGS_binary_input) { - serialized_request_proto = request_text; - request_text.clear(); - } else { - serialized_request_proto = parser->GetSerializedProtoFromMethod( + while (!request_text.empty() || + (!input_stream->eof() && getline(*input_stream, line))) { + if (!request_text.empty()) { + if (FLAGS_binary_input) { + serialized_request_proto = request_text; + request_text.clear(); + } else { + serialized_request_proto = parser->GetSerializedProtoFromMethod( method_name, request_text, true /* is_request */, FLAGS_json_input); - request_text.clear(); - if (parser->HasError()) { - if (print_mode) { - fprintf(stderr, "Failed to parse request.\n"); - } - continue; - } - } - + request_text.clear(); + if (parser->HasError()) { + if (print_mode) { + fprintf(stderr, "Failed to parse request.\n"); + } + continue; + } + } + TString serialized_response_proto; - std::multimap<grpc::string_ref, grpc::string_ref> - server_initial_metadata, server_trailing_metadata; + std::multimap<grpc::string_ref, grpc::string_ref> + server_initial_metadata, server_trailing_metadata; CliCall call(channel, formatted_method_name, client_metadata, cli_args); if (FLAGS_display_peer_address) { @@ -692,258 +692,258 @@ bool GrpcTool::CallMethod(int argc, const char** argv, "New call for method_name:%s has peer address:|%s|\n", formatted_method_name.c_str(), call.peer().c_str()); } - call.Write(serialized_request_proto); - call.WritesDone(); - if (!call.Read(&serialized_response_proto, - &server_initial_metadata)) { - fprintf(stderr, "Failed to read response.\n"); - } - Status status = call.Finish(&server_trailing_metadata); - - if (status.ok()) { - if (print_mode) { - fprintf(stderr, "Rpc succeeded with OK status.\n"); - PrintMetadata(server_initial_metadata, - "Received initial metadata from server:"); - PrintMetadata(server_trailing_metadata, - "Received trailing metadata from server:"); - } - - if (FLAGS_binary_output) { - if (!callback(serialized_response_proto)) { - break; - } - } else { + call.Write(serialized_request_proto); + call.WritesDone(); + if (!call.Read(&serialized_response_proto, + &server_initial_metadata)) { + fprintf(stderr, "Failed to read response.\n"); + } + Status status = call.Finish(&server_trailing_metadata); + + if (status.ok()) { + if (print_mode) { + fprintf(stderr, "Rpc succeeded with OK status.\n"); + PrintMetadata(server_initial_metadata, + "Received initial metadata from server:"); + PrintMetadata(server_trailing_metadata, + "Received trailing metadata from server:"); + } + + if (FLAGS_binary_output) { + if (!callback(serialized_response_proto)) { + break; + } + } else { TString response_text = parser->GetFormattedStringFromMethod( - method_name, serialized_response_proto, + method_name, serialized_response_proto, false /* is_request */, FLAGS_json_output); - if (parser->HasError() && print_mode) { - fprintf(stderr, "Failed to parse response.\n"); - } else { - if (!callback(response_text)) { - break; - } - } - } - } else { - if (print_mode) { - fprintf(stderr, - "Rpc failed with status code %d, error message: %s\n", - status.error_code(), status.error_message().c_str()); - } - } - } else { - if (line.length() == 0) { - request_text = request_ss.str(); + if (parser->HasError() && print_mode) { + fprintf(stderr, "Failed to parse response.\n"); + } else { + if (!callback(response_text)) { + break; + } + } + } + } else { + if (print_mode) { + fprintf(stderr, + "Rpc failed with status code %d, error message: %s\n", + status.error_code(), status.error_message().c_str()); + } + } + } else { + if (line.length() == 0) { + request_text = request_ss.str(); request_ss.str(TString()); - request_ss.clear(); - } else { - request_ss << line << ' '; - } - } - } - - if (input_file.is_open()) { - input_file.close(); - } - - return true; - } - - if (argc == 3) { - if (!FLAGS_infile.empty()) { - fprintf(stderr, "warning: request given in argv, ignoring --infile\n"); - } - } else { - std::stringstream input_stream; - if (FLAGS_infile.empty()) { - if (isatty(fileno(stdin))) { - fprintf(stderr, "reading request message from stdin...\n"); - } - input_stream << std::cin.rdbuf(); - } else { - std::ifstream input_file(FLAGS_infile, std::ios::in | std::ios::binary); - input_stream << input_file.rdbuf(); - input_file.close(); - } - request_text = input_stream.str(); - } - - if (FLAGS_binary_input) { - serialized_request_proto = request_text; - } else { - serialized_request_proto = parser->GetSerializedProtoFromMethod( + request_ss.clear(); + } else { + request_ss << line << ' '; + } + } + } + + if (input_file.is_open()) { + input_file.close(); + } + + return true; + } + + if (argc == 3) { + if (!FLAGS_infile.empty()) { + fprintf(stderr, "warning: request given in argv, ignoring --infile\n"); + } + } else { + std::stringstream input_stream; + if (FLAGS_infile.empty()) { + if (isatty(fileno(stdin))) { + fprintf(stderr, "reading request message from stdin...\n"); + } + input_stream << std::cin.rdbuf(); + } else { + std::ifstream input_file(FLAGS_infile, std::ios::in | std::ios::binary); + input_stream << input_file.rdbuf(); + input_file.close(); + } + request_text = input_stream.str(); + } + + if (FLAGS_binary_input) { + serialized_request_proto = request_text; + } else { + serialized_request_proto = parser->GetSerializedProtoFromMethod( method_name, request_text, true /* is_request */, FLAGS_json_input); - if (parser->HasError()) { + if (parser->HasError()) { fprintf(stderr, "Failed to parse request.\n"); - return false; - } - } - fprintf(stderr, "connecting to %s\n", server_address.c_str()); - + return false; + } + } + fprintf(stderr, "connecting to %s\n", server_address.c_str()); + TString serialized_response_proto; std::multimap<TString, TString> client_metadata; - std::multimap<grpc::string_ref, grpc::string_ref> server_initial_metadata, - server_trailing_metadata; - ParseMetadataFlag(&client_metadata); - PrintMetadata(client_metadata, "Sending client initial metadata:"); - + std::multimap<grpc::string_ref, grpc::string_ref> server_initial_metadata, + server_trailing_metadata; + ParseMetadataFlag(&client_metadata); + PrintMetadata(client_metadata, "Sending client initial metadata:"); + CliCall call(channel, formatted_method_name, client_metadata, cli_args); if (FLAGS_display_peer_address) { fprintf(stderr, "New call for method_name:%s has peer address:|%s|\n", formatted_method_name.c_str(), call.peer().c_str()); } - call.Write(serialized_request_proto); - call.WritesDone(); - - for (bool receive_initial_metadata = true; call.Read( - &serialized_response_proto, - receive_initial_metadata ? &server_initial_metadata : nullptr); - receive_initial_metadata = false) { - if (!FLAGS_binary_output) { + call.Write(serialized_request_proto); + call.WritesDone(); + + for (bool receive_initial_metadata = true; call.Read( + &serialized_response_proto, + receive_initial_metadata ? &server_initial_metadata : nullptr); + receive_initial_metadata = false) { + if (!FLAGS_binary_output) { serialized_response_proto = parser->GetFormattedStringFromMethod( method_name, serialized_response_proto, false /* is_request */, FLAGS_json_output); - if (parser->HasError()) { + if (parser->HasError()) { fprintf(stderr, "Failed to parse response.\n"); - return false; - } - } - - if (receive_initial_metadata) { - PrintMetadata(server_initial_metadata, - "Received initial metadata from server:"); - } - if (!callback(serialized_response_proto)) { - return false; - } - } - Status status = call.Finish(&server_trailing_metadata); - PrintMetadata(server_trailing_metadata, - "Received trailing metadata from server:"); - if (status.ok()) { - fprintf(stderr, "Rpc succeeded with OK status\n"); - return true; - } else { - fprintf(stderr, "Rpc failed with status code %d, error message: %s\n", - status.error_code(), status.error_message().c_str()); - return false; - } - } - GPR_UNREACHABLE_CODE(return false); -} - -bool GrpcTool::ParseMessage(int argc, const char** argv, - const CliCredentials& cred, - GrpcToolOutputCallback callback) { - CommandUsage( - "Parse message\n" - " grpc_cli parse <address> <type> [<message>]\n" - " <address> ; host:port\n" - " <type> ; Protocol buffer type name\n" - " <message> ; Text protobuffer (overrides --infile)\n" - " --protofiles ; Comma separated proto files used as a" - " fallback when parsing request/response\n" - " --proto_path ; The search path of proto files, valid" - " only when --protofiles is given\n" + return false; + } + } + + if (receive_initial_metadata) { + PrintMetadata(server_initial_metadata, + "Received initial metadata from server:"); + } + if (!callback(serialized_response_proto)) { + return false; + } + } + Status status = call.Finish(&server_trailing_metadata); + PrintMetadata(server_trailing_metadata, + "Received trailing metadata from server:"); + if (status.ok()) { + fprintf(stderr, "Rpc succeeded with OK status\n"); + return true; + } else { + fprintf(stderr, "Rpc failed with status code %d, error message: %s\n", + status.error_code(), status.error_message().c_str()); + return false; + } + } + GPR_UNREACHABLE_CODE(return false); +} + +bool GrpcTool::ParseMessage(int argc, const char** argv, + const CliCredentials& cred, + GrpcToolOutputCallback callback) { + CommandUsage( + "Parse message\n" + " grpc_cli parse <address> <type> [<message>]\n" + " <address> ; host:port\n" + " <type> ; Protocol buffer type name\n" + " <message> ; Text protobuffer (overrides --infile)\n" + " --protofiles ; Comma separated proto files used as a" + " fallback when parsing request/response\n" + " --proto_path ; The search path of proto files, valid" + " only when --protofiles is given\n" " --noremotedb ; Don't attempt to use reflection service" " at all\n" - " --infile ; Input filename (defaults to stdin)\n" - " --outfile ; Output filename (defaults to stdout)\n" - " --binary_input ; Input in binary format\n" + " --infile ; Input filename (defaults to stdin)\n" + " --outfile ; Output filename (defaults to stdout)\n" + " --binary_input ; Input in binary format\n" " --binary_output ; Output in binary format\n" " --json_input ; Input in json format\n" " --json_output ; Output in json format\n" + - cred.GetCredentialUsage()); - - std::stringstream output_ss; + cred.GetCredentialUsage()); + + std::stringstream output_ss; TString message_text; TString server_address(argv[0]); TString type_name(argv[1]); - std::unique_ptr<grpc::testing::ProtoFileParser> parser; + std::unique_ptr<grpc::testing::ProtoFileParser> parser; TString serialized_request_proto; - - if (argc == 3) { - message_text = argv[2]; - if (!FLAGS_infile.empty()) { - fprintf(stderr, "warning: message given in argv, ignoring --infile.\n"); - } - } else { - std::stringstream input_stream; - if (FLAGS_infile.empty()) { - if (isatty(fileno(stdin))) { - fprintf(stderr, "reading request message from stdin...\n"); - } - input_stream << std::cin.rdbuf(); - } else { - std::ifstream input_file(FLAGS_infile, std::ios::in | std::ios::binary); - input_stream << input_file.rdbuf(); - input_file.close(); - } - message_text = input_stream.str(); - } - - if (!FLAGS_binary_input || !FLAGS_binary_output) { - std::shared_ptr<grpc::Channel> channel = + + if (argc == 3) { + message_text = argv[2]; + if (!FLAGS_infile.empty()) { + fprintf(stderr, "warning: message given in argv, ignoring --infile.\n"); + } + } else { + std::stringstream input_stream; + if (FLAGS_infile.empty()) { + if (isatty(fileno(stdin))) { + fprintf(stderr, "reading request message from stdin...\n"); + } + input_stream << std::cin.rdbuf(); + } else { + std::ifstream input_file(FLAGS_infile, std::ios::in | std::ios::binary); + input_stream << input_file.rdbuf(); + input_file.close(); + } + message_text = input_stream.str(); + } + + if (!FLAGS_binary_input || !FLAGS_binary_output) { + std::shared_ptr<grpc::Channel> channel = CreateCliChannel(server_address, cred); - parser.reset( - new grpc::testing::ProtoFileParser(FLAGS_remotedb ? channel : nullptr, + parser.reset( + new grpc::testing::ProtoFileParser(FLAGS_remotedb ? channel : nullptr, FLAGS_proto_path.c_str(), FLAGS_protofiles.c_str())); - if (parser->HasError()) { + if (parser->HasError()) { fprintf( stderr, "Failed to find remote reflection service and local proto files.\n"); - return false; - } - } - - if (FLAGS_binary_input) { - serialized_request_proto = message_text; - } else { + return false; + } + } + + if (FLAGS_binary_input) { + serialized_request_proto = message_text; + } else { serialized_request_proto = parser->GetSerializedProtoFromMessageType( type_name, message_text, FLAGS_json_input); - if (parser->HasError()) { + if (parser->HasError()) { fprintf(stderr, "Failed to serialize the message.\n"); - return false; - } - } - - if (FLAGS_binary_output) { - output_ss << serialized_request_proto; - } else { + return false; + } + } + + if (FLAGS_binary_output) { + output_ss << serialized_request_proto; + } else { TString output_text; output_text = parser->GetFormattedStringFromMessageType( type_name, serialized_request_proto, FLAGS_json_output); - if (parser->HasError()) { + if (parser->HasError()) { fprintf(stderr, "Failed to deserialize the message.\n"); - return false; - } - - output_ss << output_text << std::endl; - } - - return callback(output_ss.str()); -} - -bool GrpcTool::ToText(int argc, const char** argv, const CliCredentials& cred, - GrpcToolOutputCallback callback) { - CommandUsage( - "Convert binary message to text\n" - " grpc_cli totext <protofiles> <type>\n" - " <protofiles> ; Comma separated list of proto files\n" - " <type> ; Protocol buffer type name\n" - " --proto_path ; The search path of proto files\n" - " --infile ; Input filename (defaults to stdin)\n" - " --outfile ; Output filename (defaults to stdout)\n"); - - FLAGS_protofiles = argv[0]; - FLAGS_remotedb = false; - FLAGS_binary_input = true; - FLAGS_binary_output = false; - return ParseMessage(argc, argv, cred, callback); -} - + return false; + } + + output_ss << output_text << std::endl; + } + + return callback(output_ss.str()); +} + +bool GrpcTool::ToText(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback) { + CommandUsage( + "Convert binary message to text\n" + " grpc_cli totext <protofiles> <type>\n" + " <protofiles> ; Comma separated list of proto files\n" + " <type> ; Protocol buffer type name\n" + " --proto_path ; The search path of proto files\n" + " --infile ; Input filename (defaults to stdin)\n" + " --outfile ; Output filename (defaults to stdout)\n"); + + FLAGS_protofiles = argv[0]; + FLAGS_remotedb = false; + FLAGS_binary_input = true; + FLAGS_binary_output = false; + return ParseMessage(argc, argv, cred, callback); +} + bool GrpcTool::ToJson(int argc, const char** argv, const CliCredentials& cred, GrpcToolOutputCallback callback) { CommandUsage( @@ -963,23 +963,23 @@ bool GrpcTool::ToJson(int argc, const char** argv, const CliCredentials& cred, return ParseMessage(argc, argv, cred, callback); } -bool GrpcTool::ToBinary(int argc, const char** argv, const CliCredentials& cred, - GrpcToolOutputCallback callback) { - CommandUsage( - "Convert text message to binary\n" - " grpc_cli tobinary <protofiles> <type> [<message>]\n" - " <protofiles> ; Comma separated list of proto files\n" - " <type> ; Protocol buffer type name\n" - " --proto_path ; The search path of proto files\n" - " --infile ; Input filename (defaults to stdin)\n" - " --outfile ; Output filename (defaults to stdout)\n"); - - FLAGS_protofiles = argv[0]; - FLAGS_remotedb = false; - FLAGS_binary_input = false; - FLAGS_binary_output = true; - return ParseMessage(argc, argv, cred, callback); -} - -} // namespace testing -} // namespace grpc +bool GrpcTool::ToBinary(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback) { + CommandUsage( + "Convert text message to binary\n" + " grpc_cli tobinary <protofiles> <type> [<message>]\n" + " <protofiles> ; Comma separated list of proto files\n" + " <type> ; Protocol buffer type name\n" + " --proto_path ; The search path of proto files\n" + " --infile ; Input filename (defaults to stdin)\n" + " --outfile ; Output filename (defaults to stdout)\n"); + + FLAGS_protofiles = argv[0]; + FLAGS_remotedb = false; + FLAGS_binary_input = false; + FLAGS_binary_output = true; + return ParseMessage(argc, argv, cred, callback); +} + +} // namespace testing +} // namespace grpc diff --git a/contrib/libs/grpc/test/cpp/util/grpc_tool.h b/contrib/libs/grpc/test/cpp/util/grpc_tool.h index 5bb43430d3f..da651a8bea5 100644 --- a/contrib/libs/grpc/test/cpp/util/grpc_tool.h +++ b/contrib/libs/grpc/test/cpp/util/grpc_tool.h @@ -1,39 +1,39 @@ -/* - * - * Copyright 2016 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. - * - */ - -#ifndef GRPC_TEST_CPP_UTIL_GRPC_TOOL_H -#define GRPC_TEST_CPP_UTIL_GRPC_TOOL_H - -#include <functional> - -#include <grpcpp/support/config.h> - -#include "test/cpp/util/cli_credentials.h" - -namespace grpc { -namespace testing { - +/* + * + * Copyright 2016 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. + * + */ + +#ifndef GRPC_TEST_CPP_UTIL_GRPC_TOOL_H +#define GRPC_TEST_CPP_UTIL_GRPC_TOOL_H + +#include <functional> + +#include <grpcpp/support/config.h> + +#include "test/cpp/util/cli_credentials.h" + +namespace grpc { +namespace testing { + typedef std::function<bool(const TString&)> GrpcToolOutputCallback; - -int GrpcToolMainLib(int argc, const char** argv, const CliCredentials& cred, - GrpcToolOutputCallback callback); - -} // namespace testing -} // namespace grpc - -#endif // GRPC_TEST_CPP_UTIL_GRPC_TOOL_H + +int GrpcToolMainLib(int argc, const char** argv, const CliCredentials& cred, + GrpcToolOutputCallback callback); + +} // namespace testing +} // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_GRPC_TOOL_H diff --git a/contrib/libs/grpc/test/cpp/util/grpc_tool_test.cc b/contrib/libs/grpc/test/cpp/util/grpc_tool_test.cc index ff610daadd6..b47bf6478e3 100644 --- a/contrib/libs/grpc/test/cpp/util/grpc_tool_test.cc +++ b/contrib/libs/grpc/test/cpp/util/grpc_tool_test.cc @@ -1,68 +1,68 @@ -/* - * - * Copyright 2016 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 "test/cpp/util/grpc_tool.h" - -#include <gflags/gflags.h> -#include <grpc/grpc.h> -#include <grpc/support/alloc.h> -#include <grpcpp/channel.h> -#include <grpcpp/client_context.h> -#include <grpcpp/create_channel.h> -#include <grpcpp/ext/proto_server_reflection_plugin.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> -#include <grpcpp/server_context.h> -#include <gtest/gtest.h> - +/* + * + * Copyright 2016 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 "test/cpp/util/grpc_tool.h" + +#include <gflags/gflags.h> +#include <grpc/grpc.h> +#include <grpc/support/alloc.h> +#include <grpcpp/channel.h> +#include <grpcpp/client_context.h> +#include <grpcpp/create_channel.h> +#include <grpcpp/ext/proto_server_reflection_plugin.h> +#include <grpcpp/server.h> +#include <grpcpp/server_builder.h> +#include <grpcpp/server_context.h> +#include <gtest/gtest.h> + #include <chrono> #include <sstream> -#include "src/core/lib/gpr/env.h" +#include "src/core/lib/gpr/env.h" #include "src/core/lib/iomgr/load_file.h" -#include "src/proto/grpc/testing/echo.grpc.pb.h" -#include "src/proto/grpc/testing/echo.pb.h" -#include "test/core/util/port.h" -#include "test/core/util/test_config.h" -#include "test/cpp/util/cli_credentials.h" -#include "test/cpp/util/string_ref_helper.h" - +#include "src/proto/grpc/testing/echo.grpc.pb.h" +#include "src/proto/grpc/testing/echo.pb.h" +#include "test/core/util/port.h" +#include "test/core/util/test_config.h" +#include "test/cpp/util/cli_credentials.h" +#include "test/cpp/util/string_ref_helper.h" + #define CA_CERT_PATH "src/core/tsi/test_creds/ca.pem" #define SERVER_CERT_PATH "src/core/tsi/test_creds/server1.pem" #define SERVER_KEY_PATH "src/core/tsi/test_creds/server1.key" -using grpc::testing::EchoRequest; -using grpc::testing::EchoResponse; - -#define USAGE_REGEX "( grpc_cli .+\n){2,10}" - -#define ECHO_TEST_SERVICE_SUMMARY \ - "Echo\n" \ +using grpc::testing::EchoRequest; +using grpc::testing::EchoResponse; + +#define USAGE_REGEX "( grpc_cli .+\n){2,10}" + +#define ECHO_TEST_SERVICE_SUMMARY \ + "Echo\n" \ "Echo1\n" \ "Echo2\n" \ "CheckDeadlineUpperBound\n" \ "CheckDeadlineSet\n" \ "CheckClientInitialMetadata\n" \ - "RequestStream\n" \ - "ResponseStream\n" \ - "BidiStream\n" \ - "Unimplemented\n" - + "RequestStream\n" \ + "ResponseStream\n" \ + "BidiStream\n" \ + "Unimplemented\n" + #define ECHO_TEST_SERVICE_DESCRIPTION \ "filename: src/proto/grpc/testing/echo.proto\n" \ "package: grpc.testing;\n" \ @@ -88,19 +88,19 @@ using grpc::testing::EchoResponse; " rpc Unimplemented(grpc.testing.EchoRequest) returns " \ "(grpc.testing.EchoResponse) {}\n" \ "}\n" \ - "\n" - -#define ECHO_METHOD_DESCRIPTION \ - " rpc Echo(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse) " \ - "{}\n" - + "\n" + +#define ECHO_METHOD_DESCRIPTION \ + " rpc Echo(grpc.testing.EchoRequest) returns (grpc.testing.EchoResponse) " \ + "{}\n" + #define ECHO_RESPONSE_MESSAGE_TEXT_FORMAT \ "message: \"echo\"\n" \ "param {\n" \ " host: \"localhost\"\n" \ " peer: \"peer\"\n" \ - "}\n\n" - + "}\n\n" + #define ECHO_RESPONSE_MESSAGE_JSON_FORMAT \ "{\n" \ " \"message\": \"echo\",\n" \ @@ -113,27 +113,27 @@ using grpc::testing::EchoResponse; DECLARE_string(channel_creds_type); DECLARE_string(ssl_target); -namespace grpc { -namespace testing { - -DECLARE_bool(binary_input); -DECLARE_bool(binary_output); +namespace grpc { +namespace testing { + +DECLARE_bool(binary_input); +DECLARE_bool(binary_output); DECLARE_bool(json_input); DECLARE_bool(json_output); -DECLARE_bool(l); -DECLARE_bool(batch); -DECLARE_string(metadata); -DECLARE_string(protofiles); -DECLARE_string(proto_path); +DECLARE_bool(l); +DECLARE_bool(batch); +DECLARE_string(metadata); +DECLARE_string(protofiles); +DECLARE_string(proto_path); DECLARE_string(default_service_config); DECLARE_double(timeout); - -namespace { - -const int kServerDefaultResponseStreamsToSend = 3; - -class TestCliCredentials final : public grpc::testing::CliCredentials { - public: + +namespace { + +const int kServerDefaultResponseStreamsToSend = 3; + +class TestCliCredentials final : public grpc::testing::CliCredentials { + public: TestCliCredentials(bool secure = false) : secure_(secure) {} std::shared_ptr<grpc::ChannelCredentials> GetChannelCredentials() const override { @@ -150,41 +150,41 @@ class TestCliCredentials final : public grpc::testing::CliCredentials { grpc::SslCredentials(grpc::SslCredentialsOptions(ssl_opts)); grpc_slice_unref(ca_slice); return credential_ptr; - } + } const TString GetCredentialUsage() const override { return ""; } private: const bool secure_; -}; - +}; + bool PrintStream(std::stringstream* ss, const TString& output) { - (*ss) << output; - return true; -} - -template <typename T> -size_t ArraySize(T& a) { - return ((sizeof(a) / sizeof(*(a))) / - static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))); -} - -class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { - public: - Status Echo(ServerContext* context, const EchoRequest* request, - EchoResponse* response) override { - if (!context->client_metadata().empty()) { - for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator - iter = context->client_metadata().begin(); - iter != context->client_metadata().end(); ++iter) { - context->AddInitialMetadata(ToString(iter->first), - ToString(iter->second)); - } - } - context->AddTrailingMetadata("trailing_key", "trailing_value"); - response->set_message(request->message()); - return Status::OK; - } - + (*ss) << output; + return true; +} + +template <typename T> +size_t ArraySize(T& a) { + return ((sizeof(a) / sizeof(*(a))) / + static_cast<size_t>(!(sizeof(a) % sizeof(*(a))))); +} + +class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { + public: + Status Echo(ServerContext* context, const EchoRequest* request, + EchoResponse* response) override { + if (!context->client_metadata().empty()) { + for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator + iter = context->client_metadata().begin(); + iter != context->client_metadata().end(); ++iter) { + context->AddInitialMetadata(ToString(iter->first), + ToString(iter->second)); + } + } + context->AddTrailingMetadata("trailing_key", "trailing_value"); + response->set_message(request->message()); + return Status::OK; + } + Status CheckDeadlineSet(ServerContext* context, const SimpleRequest* request, StringValue* response) override { response->set_message(context->deadline() != @@ -208,87 +208,87 @@ class TestServiceImpl : public ::grpc::testing::EchoTestService::Service { return Status::OK; } - Status RequestStream(ServerContext* context, - ServerReader<EchoRequest>* reader, - EchoResponse* response) override { - EchoRequest request; - response->set_message(""); - if (!context->client_metadata().empty()) { - for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator - iter = context->client_metadata().begin(); - iter != context->client_metadata().end(); ++iter) { - context->AddInitialMetadata(ToString(iter->first), - ToString(iter->second)); - } - } - context->AddTrailingMetadata("trailing_key", "trailing_value"); - while (reader->Read(&request)) { - response->mutable_message()->append(request.message()); - } - - return Status::OK; - } - - Status ResponseStream(ServerContext* context, const EchoRequest* request, - ServerWriter<EchoResponse>* writer) override { - if (!context->client_metadata().empty()) { - for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator - iter = context->client_metadata().begin(); - iter != context->client_metadata().end(); ++iter) { - context->AddInitialMetadata(ToString(iter->first), - ToString(iter->second)); - } - } - context->AddTrailingMetadata("trailing_key", "trailing_value"); - - EchoResponse response; - for (int i = 0; i < kServerDefaultResponseStreamsToSend; i++) { + Status RequestStream(ServerContext* context, + ServerReader<EchoRequest>* reader, + EchoResponse* response) override { + EchoRequest request; + response->set_message(""); + if (!context->client_metadata().empty()) { + for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator + iter = context->client_metadata().begin(); + iter != context->client_metadata().end(); ++iter) { + context->AddInitialMetadata(ToString(iter->first), + ToString(iter->second)); + } + } + context->AddTrailingMetadata("trailing_key", "trailing_value"); + while (reader->Read(&request)) { + response->mutable_message()->append(request.message()); + } + + return Status::OK; + } + + Status ResponseStream(ServerContext* context, const EchoRequest* request, + ServerWriter<EchoResponse>* writer) override { + if (!context->client_metadata().empty()) { + for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator + iter = context->client_metadata().begin(); + iter != context->client_metadata().end(); ++iter) { + context->AddInitialMetadata(ToString(iter->first), + ToString(iter->second)); + } + } + context->AddTrailingMetadata("trailing_key", "trailing_value"); + + EchoResponse response; + for (int i = 0; i < kServerDefaultResponseStreamsToSend; i++) { response.set_message(request->message() + ToString(i)); - writer->Write(response); - } - - return Status::OK; - } - - Status BidiStream( - ServerContext* context, - ServerReaderWriter<EchoResponse, EchoRequest>* stream) override { - EchoRequest request; - EchoResponse response; - if (!context->client_metadata().empty()) { - for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator - iter = context->client_metadata().begin(); - iter != context->client_metadata().end(); ++iter) { - context->AddInitialMetadata(ToString(iter->first), - ToString(iter->second)); - } - } - context->AddTrailingMetadata("trailing_key", "trailing_value"); - - while (stream->Read(&request)) { - response.set_message(request.message()); - stream->Write(response); - } - - return Status::OK; - } -}; - -} // namespace - -class GrpcToolTest : public ::testing::Test { - protected: - GrpcToolTest() {} - - // SetUpServer cannot be used with EXPECT_EXIT. grpc_pick_unused_port_or_die() - // uses atexit() to free chosen ports, and it will spawn a new thread in - // resolve_address_posix.c:192 at exit time. + writer->Write(response); + } + + return Status::OK; + } + + Status BidiStream( + ServerContext* context, + ServerReaderWriter<EchoResponse, EchoRequest>* stream) override { + EchoRequest request; + EchoResponse response; + if (!context->client_metadata().empty()) { + for (std::multimap<grpc::string_ref, grpc::string_ref>::const_iterator + iter = context->client_metadata().begin(); + iter != context->client_metadata().end(); ++iter) { + context->AddInitialMetadata(ToString(iter->first), + ToString(iter->second)); + } + } + context->AddTrailingMetadata("trailing_key", "trailing_value"); + + while (stream->Read(&request)) { + response.set_message(request.message()); + stream->Write(response); + } + + return Status::OK; + } +}; + +} // namespace + +class GrpcToolTest : public ::testing::Test { + protected: + GrpcToolTest() {} + + // SetUpServer cannot be used with EXPECT_EXIT. grpc_pick_unused_port_or_die() + // uses atexit() to free chosen ports, and it will spawn a new thread in + // resolve_address_posix.c:192 at exit time. const TString SetUpServer(bool secure = false) { - std::ostringstream server_address; - int port = grpc_pick_unused_port_or_die(); - server_address << "localhost:" << port; - // Setup server - ServerBuilder builder; + std::ostringstream server_address; + int port = grpc_pick_unused_port_or_die(); + server_address << "localhost:" << port; + // Setup server + ServerBuilder builder; std::shared_ptr<grpc::ServerCredentials> creds; grpc_slice cert_slice, key_slice; GPR_ASSERT(GRPC_LOG_IF_ERROR( @@ -310,187 +310,187 @@ class GrpcToolTest : public ::testing::Test { creds = InsecureServerCredentials(); } builder.AddListeningPort(server_address.str(), creds); - builder.RegisterService(&service_); - server_ = builder.BuildAndStart(); + builder.RegisterService(&service_); + server_ = builder.BuildAndStart(); grpc_slice_unref(cert_slice); grpc_slice_unref(key_slice); - return server_address.str(); - } - - void ShutdownServer() { server_->Shutdown(); } - - std::unique_ptr<Server> server_; - TestServiceImpl service_; - reflection::ProtoServerReflectionPlugin plugin_; -}; - -TEST_F(GrpcToolTest, NoCommand) { - // Test input "grpc_cli" - std::stringstream output_stream; - const char* argv[] = {"grpc_cli"}; - // Exit with 1, print usage instruction in stderr - EXPECT_EXIT( - GrpcToolMainLib( - ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, std::placeholders::_1)), - ::testing::ExitedWithCode(1), "No command specified\n" USAGE_REGEX); - // No output - EXPECT_TRUE(0 == output_stream.tellp()); -} - -TEST_F(GrpcToolTest, InvalidCommand) { - // Test input "grpc_cli" - std::stringstream output_stream; - const char* argv[] = {"grpc_cli", "abc"}; - // Exit with 1, print usage instruction in stderr - EXPECT_EXIT( - GrpcToolMainLib( - ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, std::placeholders::_1)), - ::testing::ExitedWithCode(1), "Invalid command 'abc'\n" USAGE_REGEX); - // No output - EXPECT_TRUE(0 == output_stream.tellp()); -} - -TEST_F(GrpcToolTest, HelpCommand) { - // Test input "grpc_cli help" - std::stringstream output_stream; - const char* argv[] = {"grpc_cli", "help"}; - // Exit with 1, print usage instruction in stderr - EXPECT_EXIT(GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1)), - ::testing::ExitedWithCode(1), USAGE_REGEX); - // No output - EXPECT_TRUE(0 == output_stream.tellp()); -} - -TEST_F(GrpcToolTest, ListCommand) { - // Test input "grpc_cli list localhost:<port>" - std::stringstream output_stream; - + return server_address.str(); + } + + void ShutdownServer() { server_->Shutdown(); } + + std::unique_ptr<Server> server_; + TestServiceImpl service_; + reflection::ProtoServerReflectionPlugin plugin_; +}; + +TEST_F(GrpcToolTest, NoCommand) { + // Test input "grpc_cli" + std::stringstream output_stream; + const char* argv[] = {"grpc_cli"}; + // Exit with 1, print usage instruction in stderr + EXPECT_EXIT( + GrpcToolMainLib( + ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, std::placeholders::_1)), + ::testing::ExitedWithCode(1), "No command specified\n" USAGE_REGEX); + // No output + EXPECT_TRUE(0 == output_stream.tellp()); +} + +TEST_F(GrpcToolTest, InvalidCommand) { + // Test input "grpc_cli" + std::stringstream output_stream; + const char* argv[] = {"grpc_cli", "abc"}; + // Exit with 1, print usage instruction in stderr + EXPECT_EXIT( + GrpcToolMainLib( + ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, std::placeholders::_1)), + ::testing::ExitedWithCode(1), "Invalid command 'abc'\n" USAGE_REGEX); + // No output + EXPECT_TRUE(0 == output_stream.tellp()); +} + +TEST_F(GrpcToolTest, HelpCommand) { + // Test input "grpc_cli help" + std::stringstream output_stream; + const char* argv[] = {"grpc_cli", "help"}; + // Exit with 1, print usage instruction in stderr + EXPECT_EXIT(GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1)), + ::testing::ExitedWithCode(1), USAGE_REGEX); + // No output + EXPECT_TRUE(0 == output_stream.tellp()); +} + +TEST_F(GrpcToolTest, ListCommand) { + // Test input "grpc_cli list localhost:<port>" + std::stringstream output_stream; + const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "ls", server_address.c_str()}; - - FLAGS_l = false; - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), - "grpc.testing.EchoTestService\n" - "grpc.reflection.v1alpha.ServerReflection\n")); - - ShutdownServer(); -} - -TEST_F(GrpcToolTest, ListOneService) { - // Test input "grpc_cli list localhost:<port> grpc.testing.EchoTestService" - std::stringstream output_stream; - + const char* argv[] = {"grpc_cli", "ls", server_address.c_str()}; + + FLAGS_l = false; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), + "grpc.testing.EchoTestService\n" + "grpc.reflection.v1alpha.ServerReflection\n")); + + ShutdownServer(); +} + +TEST_F(GrpcToolTest, ListOneService) { + // Test input "grpc_cli list localhost:<port> grpc.testing.EchoTestService" + std::stringstream output_stream; + const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "ls", server_address.c_str(), - "grpc.testing.EchoTestService"}; - // without -l flag - FLAGS_l = false; - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - // Expected output: ECHO_TEST_SERVICE_SUMMARY - EXPECT_TRUE(0 == - strcmp(output_stream.str().c_str(), ECHO_TEST_SERVICE_SUMMARY)); - - // with -l flag + const char* argv[] = {"grpc_cli", "ls", server_address.c_str(), + "grpc.testing.EchoTestService"}; + // without -l flag + FLAGS_l = false; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + // Expected output: ECHO_TEST_SERVICE_SUMMARY + EXPECT_TRUE(0 == + strcmp(output_stream.str().c_str(), ECHO_TEST_SERVICE_SUMMARY)); + + // with -l flag output_stream.str(TString()); - output_stream.clear(); - FLAGS_l = true; - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - // Expected output: ECHO_TEST_SERVICE_DESCRIPTION - EXPECT_TRUE( - 0 == strcmp(output_stream.str().c_str(), ECHO_TEST_SERVICE_DESCRIPTION)); - - ShutdownServer(); -} - -TEST_F(GrpcToolTest, TypeCommand) { - // Test input "grpc_cli type localhost:<port> grpc.testing.EchoRequest" - std::stringstream output_stream; - + output_stream.clear(); + FLAGS_l = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + // Expected output: ECHO_TEST_SERVICE_DESCRIPTION + EXPECT_TRUE( + 0 == strcmp(output_stream.str().c_str(), ECHO_TEST_SERVICE_DESCRIPTION)); + + ShutdownServer(); +} + +TEST_F(GrpcToolTest, TypeCommand) { + // Test input "grpc_cli type localhost:<port> grpc.testing.EchoRequest" + std::stringstream output_stream; + const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "type", server_address.c_str(), - "grpc.testing.EchoRequest"}; - - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - const grpc::protobuf::Descriptor* desc = - grpc::protobuf::DescriptorPool::generated_pool()->FindMessageTypeByName( - "grpc.testing.EchoRequest"); - // Expected output: the DebugString of grpc.testing.EchoRequest - EXPECT_TRUE(0 == - strcmp(output_stream.str().c_str(), desc->DebugString().c_str())); - - ShutdownServer(); -} - -TEST_F(GrpcToolTest, ListOneMethod) { - // Test input "grpc_cli list localhost:<port> grpc.testing.EchoTestService" - std::stringstream output_stream; - + const char* argv[] = {"grpc_cli", "type", server_address.c_str(), + "grpc.testing.EchoRequest"}; + + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + const grpc::protobuf::Descriptor* desc = + grpc::protobuf::DescriptorPool::generated_pool()->FindMessageTypeByName( + "grpc.testing.EchoRequest"); + // Expected output: the DebugString of grpc.testing.EchoRequest + EXPECT_TRUE(0 == + strcmp(output_stream.str().c_str(), desc->DebugString().c_str())); + + ShutdownServer(); +} + +TEST_F(GrpcToolTest, ListOneMethod) { + // Test input "grpc_cli list localhost:<port> grpc.testing.EchoTestService" + std::stringstream output_stream; + const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "ls", server_address.c_str(), - "grpc.testing.EchoTestService.Echo"}; - // without -l flag - FLAGS_l = false; - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - // Expected output: "Echo" - EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), "Echo\n")); - - // with -l flag + const char* argv[] = {"grpc_cli", "ls", server_address.c_str(), + "grpc.testing.EchoTestService.Echo"}; + // without -l flag + FLAGS_l = false; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + // Expected output: "Echo" + EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), "Echo\n")); + + // with -l flag output_stream.str(TString()); - output_stream.clear(); - FLAGS_l = true; - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - // Expected output: ECHO_METHOD_DESCRIPTION - EXPECT_TRUE(0 == - strcmp(output_stream.str().c_str(), ECHO_METHOD_DESCRIPTION)); - - ShutdownServer(); -} - -TEST_F(GrpcToolTest, TypeNotFound) { - // Test input "grpc_cli type localhost:<port> grpc.testing.DummyRequest" - std::stringstream output_stream; - + output_stream.clear(); + FLAGS_l = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + // Expected output: ECHO_METHOD_DESCRIPTION + EXPECT_TRUE(0 == + strcmp(output_stream.str().c_str(), ECHO_METHOD_DESCRIPTION)); + + ShutdownServer(); +} + +TEST_F(GrpcToolTest, TypeNotFound) { + // Test input "grpc_cli type localhost:<port> grpc.testing.DummyRequest" + std::stringstream output_stream; + const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "type", server_address.c_str(), - "grpc.testing.DummyRequest"}; - + const char* argv[] = {"grpc_cli", "type", server_address.c_str(), + "grpc.testing.DummyRequest"}; + EXPECT_TRUE(1 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), std::bind(PrintStream, &output_stream, std::placeholders::_1))); - ShutdownServer(); -} - -TEST_F(GrpcToolTest, CallCommand) { - // Test input "grpc_cli call localhost:<port> Echo "message: 'Hello'" - std::stringstream output_stream; - + ShutdownServer(); +} + +TEST_F(GrpcToolTest, CallCommand) { + // Test input "grpc_cli call localhost:<port> Echo "message: 'Hello'" + std::stringstream output_stream; + const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo", - "message: 'Hello'"}; - - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - // Expected output: "message: \"Hello\"" - EXPECT_TRUE(nullptr != - strstr(output_stream.str().c_str(), "message: \"Hello\"")); + const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo", + "message: 'Hello'"}; + + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + // Expected output: "message: \"Hello\"" + EXPECT_TRUE(nullptr != + strstr(output_stream.str().c_str(), "message: \"Hello\"")); // with json_output output_stream.str(TString()); @@ -509,9 +509,9 @@ TEST_F(GrpcToolTest, CallCommand) { EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), "{\n \"message\": \"Hello\"\n}")); - ShutdownServer(); -} - + ShutdownServer(); +} + TEST_F(GrpcToolTest, CallCommandJsonInput) { // Test input "grpc_cli call localhost:<port> Echo "{ \"message\": \"Hello\"}" std::stringstream output_stream; @@ -549,30 +549,30 @@ TEST_F(GrpcToolTest, CallCommandJsonInput) { ShutdownServer(); } -TEST_F(GrpcToolTest, CallCommandBatch) { - // Test input "grpc_cli call Echo" - std::stringstream output_stream; - +TEST_F(GrpcToolTest, CallCommandBatch) { + // Test input "grpc_cli call Echo" + std::stringstream output_stream; + const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo", - "message: 'Hello0'"}; - - // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n" - std::streambuf* orig = std::cin.rdbuf(); - std::istringstream ss("message: 'Hello1'\n\n message: 'Hello2'\n\n"); - std::cin.rdbuf(ss.rdbuf()); - - FLAGS_batch = true; - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - FLAGS_batch = false; - - // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage: - // "Hello2"\n" - EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), - "message: \"Hello0\"\nmessage: " - "\"Hello1\"\nmessage: \"Hello2\"\n")); + const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo", + "message: 'Hello0'"}; + + // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n" + std::streambuf* orig = std::cin.rdbuf(); + std::istringstream ss("message: 'Hello1'\n\n message: 'Hello2'\n\n"); + std::cin.rdbuf(ss.rdbuf()); + + FLAGS_batch = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + FLAGS_batch = false; + + // Expected output: "message: "Hello0"\nmessage: "Hello1"\nmessage: + // "Hello2"\n" + EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), + "message: \"Hello0\"\nmessage: " + "\"Hello1\"\nmessage: \"Hello2\"\n")); // with json_output output_stream.str(TString()); output_stream.clear(); @@ -605,10 +605,10 @@ TEST_F(GrpcToolTest, CallCommandBatch) { "{\n \"message\": \"Hello1\"\n}\n" "{\n \"message\": \"Hello2\"\n}\n")); - std::cin.rdbuf(orig); - ShutdownServer(); -} - + std::cin.rdbuf(orig); + ShutdownServer(); +} + TEST_F(GrpcToolTest, CallCommandBatchJsonInput) { // Test input "grpc_cli call Echo" std::stringstream output_stream; @@ -672,28 +672,28 @@ TEST_F(GrpcToolTest, CallCommandBatchJsonInput) { ShutdownServer(); } -TEST_F(GrpcToolTest, CallCommandBatchWithBadRequest) { - // Test input "grpc_cli call Echo" - std::stringstream output_stream; - +TEST_F(GrpcToolTest, CallCommandBatchWithBadRequest) { + // Test input "grpc_cli call Echo" + std::stringstream output_stream; + const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo", - "message: 'Hello0'"}; - - // Mock std::cin input "message: 1\n\n message: 'Hello2'\n\n" - std::streambuf* orig = std::cin.rdbuf(); - std::istringstream ss("message: 1\n\n message: 'Hello2'\n\n"); - std::cin.rdbuf(ss.rdbuf()); - - FLAGS_batch = true; - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - FLAGS_batch = false; - - // Expected output: "message: "Hello0"\nmessage: "Hello2"\n" - EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), - "message: \"Hello0\"\nmessage: \"Hello2\"\n")); + const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo", + "message: 'Hello0'"}; + + // Mock std::cin input "message: 1\n\n message: 'Hello2'\n\n" + std::streambuf* orig = std::cin.rdbuf(); + std::istringstream ss("message: 1\n\n message: 'Hello2'\n\n"); + std::cin.rdbuf(ss.rdbuf()); + + FLAGS_batch = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + FLAGS_batch = false; + + // Expected output: "message: "Hello0"\nmessage: "Hello2"\n" + EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), + "message: \"Hello0\"\nmessage: \"Hello2\"\n")); // with json_output output_stream.str(TString()); @@ -723,10 +723,10 @@ TEST_F(GrpcToolTest, CallCommandBatchWithBadRequest) { "{\n \"message\": \"Hello0\"\n}\n" "{\n \"message\": \"Hello2\"\n}\n")); - std::cin.rdbuf(orig); - ShutdownServer(); -} - + std::cin.rdbuf(orig); + ShutdownServer(); +} + TEST_F(GrpcToolTest, CallCommandBatchJsonInputWithBadRequest) { // Test input "grpc_cli call Echo" std::stringstream output_stream; @@ -787,31 +787,31 @@ TEST_F(GrpcToolTest, CallCommandBatchJsonInputWithBadRequest) { ShutdownServer(); } -TEST_F(GrpcToolTest, CallCommandRequestStream) { - // Test input: grpc_cli call localhost:<port> RequestStream "message: - // 'Hello0'" - std::stringstream output_stream; - +TEST_F(GrpcToolTest, CallCommandRequestStream) { + // Test input: grpc_cli call localhost:<port> RequestStream "message: + // 'Hello0'" + std::stringstream output_stream; + const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), - "RequestStream", "message: 'Hello0'"}; - - // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n" - std::streambuf* orig = std::cin.rdbuf(); - std::istringstream ss("message: 'Hello1'\n\n message: 'Hello2'\n\n"); - std::cin.rdbuf(ss.rdbuf()); - - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - - // Expected output: "message: \"Hello0Hello1Hello2\"" - EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), - "message: \"Hello0Hello1Hello2\"")); - std::cin.rdbuf(orig); - ShutdownServer(); -} - + const char* argv[] = {"grpc_cli", "call", server_address.c_str(), + "RequestStream", "message: 'Hello0'"}; + + // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n" + std::streambuf* orig = std::cin.rdbuf(); + std::istringstream ss("message: 'Hello1'\n\n message: 'Hello2'\n\n"); + std::cin.rdbuf(ss.rdbuf()); + + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + + // Expected output: "message: \"Hello0Hello1Hello2\"" + EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), + "message: \"Hello0Hello1Hello2\"")); + std::cin.rdbuf(orig); + ShutdownServer(); +} + TEST_F(GrpcToolTest, CallCommandRequestStreamJsonInput) { // Test input: grpc_cli call localhost:<port> RequestStream "{ \"message\": // \"Hello0\"}" @@ -840,31 +840,31 @@ TEST_F(GrpcToolTest, CallCommandRequestStreamJsonInput) { ShutdownServer(); } -TEST_F(GrpcToolTest, CallCommandRequestStreamWithBadRequest) { - // Test input: grpc_cli call localhost:<port> RequestStream "message: - // 'Hello0'" - std::stringstream output_stream; - +TEST_F(GrpcToolTest, CallCommandRequestStreamWithBadRequest) { + // Test input: grpc_cli call localhost:<port> RequestStream "message: + // 'Hello0'" + std::stringstream output_stream; + const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), - "RequestStream", "message: 'Hello0'"}; - - // Mock std::cin input "bad_field: 'Hello1'\n\n message: 'Hello2'\n\n" - std::streambuf* orig = std::cin.rdbuf(); - std::istringstream ss("bad_field: 'Hello1'\n\n message: 'Hello2'\n\n"); - std::cin.rdbuf(ss.rdbuf()); - - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - - // Expected output: "message: \"Hello0Hello2\"" - EXPECT_TRUE(nullptr != - strstr(output_stream.str().c_str(), "message: \"Hello0Hello2\"")); - std::cin.rdbuf(orig); - ShutdownServer(); -} - + const char* argv[] = {"grpc_cli", "call", server_address.c_str(), + "RequestStream", "message: 'Hello0'"}; + + // Mock std::cin input "bad_field: 'Hello1'\n\n message: 'Hello2'\n\n" + std::streambuf* orig = std::cin.rdbuf(); + std::istringstream ss("bad_field: 'Hello1'\n\n message: 'Hello2'\n\n"); + std::cin.rdbuf(ss.rdbuf()); + + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + + // Expected output: "message: \"Hello0Hello2\"" + EXPECT_TRUE(nullptr != + strstr(output_stream.str().c_str(), "message: \"Hello0Hello2\"")); + std::cin.rdbuf(orig); + ShutdownServer(); +} + TEST_F(GrpcToolTest, CallCommandRequestStreamWithBadRequestJsonInput) { // Test input: grpc_cli call localhost:<port> RequestStream "message: // 'Hello0'" @@ -980,27 +980,27 @@ TEST_F(GrpcToolTest, CallCommandWithDefaultTimeoutValue) { ShutdownServer(); } -TEST_F(GrpcToolTest, CallCommandResponseStream) { - // Test input: grpc_cli call localhost:<port> ResponseStream "message: - // 'Hello'" - std::stringstream output_stream; - +TEST_F(GrpcToolTest, CallCommandResponseStream) { + // Test input: grpc_cli call localhost:<port> ResponseStream "message: + // 'Hello'" + std::stringstream output_stream; + const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), - "ResponseStream", "message: 'Hello'"}; - - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - - // Expected output: "message: \"Hello{n}\"" - for (int i = 0; i < kServerDefaultResponseStreamsToSend; i++) { + const char* argv[] = {"grpc_cli", "call", server_address.c_str(), + "ResponseStream", "message: 'Hello'"}; + + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + + // Expected output: "message: \"Hello{n}\"" + for (int i = 0; i < kServerDefaultResponseStreamsToSend; i++) { TString expected_response_text = "message: \"Hello" + ToString(i) + "\"\n"; - EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), - expected_response_text.c_str())); - } - + EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), + expected_response_text.c_str())); + } + // with json_output output_stream.str(TString()); output_stream.clear(); @@ -1019,81 +1019,81 @@ TEST_F(GrpcToolTest, CallCommandResponseStream) { expected_response_text.c_str())); } - ShutdownServer(); -} - -TEST_F(GrpcToolTest, CallCommandBidiStream) { - // Test input: grpc_cli call localhost:<port> BidiStream "message: 'Hello0'" - std::stringstream output_stream; - + ShutdownServer(); +} + +TEST_F(GrpcToolTest, CallCommandBidiStream) { + // Test input: grpc_cli call localhost:<port> BidiStream "message: 'Hello0'" + std::stringstream output_stream; + const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), - "BidiStream", "message: 'Hello0'"}; - - // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n" - std::streambuf* orig = std::cin.rdbuf(); - std::istringstream ss("message: 'Hello1'\n\n message: 'Hello2'\n\n"); - std::cin.rdbuf(ss.rdbuf()); - - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - - // Expected output: "message: \"Hello0\"\nmessage: \"Hello1\"\nmessage: - // \"Hello2\"\n\n" - EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), - "message: \"Hello0\"\nmessage: " - "\"Hello1\"\nmessage: \"Hello2\"\n")); - std::cin.rdbuf(orig); - ShutdownServer(); -} - -TEST_F(GrpcToolTest, CallCommandBidiStreamWithBadRequest) { - // Test input: grpc_cli call localhost:<port> BidiStream "message: 'Hello0'" - std::stringstream output_stream; - + const char* argv[] = {"grpc_cli", "call", server_address.c_str(), + "BidiStream", "message: 'Hello0'"}; + + // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n" + std::streambuf* orig = std::cin.rdbuf(); + std::istringstream ss("message: 'Hello1'\n\n message: 'Hello2'\n\n"); + std::cin.rdbuf(ss.rdbuf()); + + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + + // Expected output: "message: \"Hello0\"\nmessage: \"Hello1\"\nmessage: + // \"Hello2\"\n\n" + EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), + "message: \"Hello0\"\nmessage: " + "\"Hello1\"\nmessage: \"Hello2\"\n")); + std::cin.rdbuf(orig); + ShutdownServer(); +} + +TEST_F(GrpcToolTest, CallCommandBidiStreamWithBadRequest) { + // Test input: grpc_cli call localhost:<port> BidiStream "message: 'Hello0'" + std::stringstream output_stream; + const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), - "BidiStream", "message: 'Hello0'"}; - - // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n" - std::streambuf* orig = std::cin.rdbuf(); - std::istringstream ss("message: 1.0\n\n message: 'Hello2'\n\n"); - std::cin.rdbuf(ss.rdbuf()); - - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - - // Expected output: "message: \"Hello0\"\nmessage: \"Hello1\"\nmessage: - // \"Hello2\"\n\n" - EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), - "message: \"Hello0\"\nmessage: \"Hello2\"\n")); - std::cin.rdbuf(orig); - - ShutdownServer(); -} - -TEST_F(GrpcToolTest, ParseCommand) { - // Test input "grpc_cli parse localhost:<port> grpc.testing.EchoResponse - // ECHO_RESPONSE_MESSAGE" - std::stringstream output_stream; - std::stringstream binary_output_stream; - + const char* argv[] = {"grpc_cli", "call", server_address.c_str(), + "BidiStream", "message: 'Hello0'"}; + + // Mock std::cin input "message: 'Hello1'\n\n message: 'Hello2'\n\n" + std::streambuf* orig = std::cin.rdbuf(); + std::istringstream ss("message: 1.0\n\n message: 'Hello2'\n\n"); + std::cin.rdbuf(ss.rdbuf()); + + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + + // Expected output: "message: \"Hello0\"\nmessage: \"Hello1\"\nmessage: + // \"Hello2\"\n\n" + EXPECT_TRUE(nullptr != strstr(output_stream.str().c_str(), + "message: \"Hello0\"\nmessage: \"Hello2\"\n")); + std::cin.rdbuf(orig); + + ShutdownServer(); +} + +TEST_F(GrpcToolTest, ParseCommand) { + // Test input "grpc_cli parse localhost:<port> grpc.testing.EchoResponse + // ECHO_RESPONSE_MESSAGE" + std::stringstream output_stream; + std::stringstream binary_output_stream; + const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "parse", server_address.c_str(), + const char* argv[] = {"grpc_cli", "parse", server_address.c_str(), "grpc.testing.EchoResponse", ECHO_RESPONSE_MESSAGE_TEXT_FORMAT}; - - FLAGS_binary_input = false; - FLAGS_binary_output = false; - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); + + FLAGS_binary_input = false; + FLAGS_binary_output = false; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); // Expected output: ECHO_RESPONSE_MESSAGE_TEXT_FORMAT EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), ECHO_RESPONSE_MESSAGE_TEXT_FORMAT)); - + // with json_output output_stream.str(TString()); output_stream.clear(); @@ -1108,32 +1108,32 @@ TEST_F(GrpcToolTest, ParseCommand) { EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), ECHO_RESPONSE_MESSAGE_JSON_FORMAT)); - // Parse text message to binary message and then parse it back to text message + // Parse text message to binary message and then parse it back to text message output_stream.str(TString()); - output_stream.clear(); - FLAGS_binary_output = true; - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); + output_stream.clear(); + FLAGS_binary_output = true; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); TString binary_data = output_stream.str(); output_stream.str(TString()); - output_stream.clear(); - argv[4] = binary_data.c_str(); - FLAGS_binary_input = true; - FLAGS_binary_output = false; - EXPECT_TRUE(0 == GrpcToolMainLib(5, argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - - // Expected output: ECHO_RESPONSE_MESSAGE + output_stream.clear(); + argv[4] = binary_data.c_str(); + FLAGS_binary_input = true; + FLAGS_binary_output = false; + EXPECT_TRUE(0 == GrpcToolMainLib(5, argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + + // Expected output: ECHO_RESPONSE_MESSAGE EXPECT_TRUE(0 == strcmp(output_stream.str().c_str(), ECHO_RESPONSE_MESSAGE_TEXT_FORMAT)); - - FLAGS_binary_input = false; - FLAGS_binary_output = false; - ShutdownServer(); -} - + + FLAGS_binary_input = false; + FLAGS_binary_output = false; + ShutdownServer(); +} + TEST_F(GrpcToolTest, ParseCommandJsonFormat) { // Test input "grpc_cli parse localhost:<port> grpc.testing.EchoResponse // ECHO_RESPONSE_MESSAGE_JSON_FORMAT" @@ -1172,122 +1172,122 @@ TEST_F(GrpcToolTest, ParseCommandJsonFormat) { ShutdownServer(); } -TEST_F(GrpcToolTest, TooFewArguments) { - // Test input "grpc_cli call Echo" - std::stringstream output_stream; - const char* argv[] = {"grpc_cli", "call", "Echo"}; - - // Exit with 1 - EXPECT_EXIT( - GrpcToolMainLib( - ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, std::placeholders::_1)), - ::testing::ExitedWithCode(1), ".*Wrong number of arguments for call.*"); - // No output - EXPECT_TRUE(0 == output_stream.tellp()); -} - -TEST_F(GrpcToolTest, TooManyArguments) { - // Test input "grpc_cli call localhost:<port> Echo Echo "message: 'Hello'" - std::stringstream output_stream; - const char* argv[] = {"grpc_cli", "call", "localhost:10000", - "Echo", "Echo", "message: 'Hello'"}; - - // Exit with 1 - EXPECT_EXIT( - GrpcToolMainLib( - ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, std::placeholders::_1)), - ::testing::ExitedWithCode(1), ".*Wrong number of arguments for call.*"); - // No output - EXPECT_TRUE(0 == output_stream.tellp()); -} - -TEST_F(GrpcToolTest, CallCommandWithMetadata) { - // Test input "grpc_cli call localhost:<port> Echo "message: 'Hello'" +TEST_F(GrpcToolTest, TooFewArguments) { + // Test input "grpc_cli call Echo" + std::stringstream output_stream; + const char* argv[] = {"grpc_cli", "call", "Echo"}; + + // Exit with 1 + EXPECT_EXIT( + GrpcToolMainLib( + ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, std::placeholders::_1)), + ::testing::ExitedWithCode(1), ".*Wrong number of arguments for call.*"); + // No output + EXPECT_TRUE(0 == output_stream.tellp()); +} + +TEST_F(GrpcToolTest, TooManyArguments) { + // Test input "grpc_cli call localhost:<port> Echo Echo "message: 'Hello'" + std::stringstream output_stream; + const char* argv[] = {"grpc_cli", "call", "localhost:10000", + "Echo", "Echo", "message: 'Hello'"}; + + // Exit with 1 + EXPECT_EXIT( + GrpcToolMainLib( + ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, std::placeholders::_1)), + ::testing::ExitedWithCode(1), ".*Wrong number of arguments for call.*"); + // No output + EXPECT_TRUE(0 == output_stream.tellp()); +} + +TEST_F(GrpcToolTest, CallCommandWithMetadata) { + // Test input "grpc_cli call localhost:<port> Echo "message: 'Hello'" const TString server_address = SetUpServer(); - const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo", - "message: 'Hello'"}; - - { - std::stringstream output_stream; - FLAGS_metadata = "key0:val0:key1:valq:key2:val2"; - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, - TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - // Expected output: "message: \"Hello\"" - EXPECT_TRUE(nullptr != - strstr(output_stream.str().c_str(), "message: \"Hello\"")); - } - - { - std::stringstream output_stream; - FLAGS_metadata = "key:val\\:val"; - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, - TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - // Expected output: "message: \"Hello\"" - EXPECT_TRUE(nullptr != - strstr(output_stream.str().c_str(), "message: \"Hello\"")); - } - - { - std::stringstream output_stream; - FLAGS_metadata = "key:val\\\\val"; - EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, - TestCliCredentials(), - std::bind(PrintStream, &output_stream, - std::placeholders::_1))); - // Expected output: "message: \"Hello\"" - EXPECT_TRUE(nullptr != - strstr(output_stream.str().c_str(), "message: \"Hello\"")); - } - - FLAGS_metadata = ""; - ShutdownServer(); -} - -TEST_F(GrpcToolTest, CallCommandWithBadMetadata) { - // Test input "grpc_cli call localhost:10000 Echo "message: 'Hello'" + const char* argv[] = {"grpc_cli", "call", server_address.c_str(), "Echo", + "message: 'Hello'"}; + + { + std::stringstream output_stream; + FLAGS_metadata = "key0:val0:key1:valq:key2:val2"; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, + TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + // Expected output: "message: \"Hello\"" + EXPECT_TRUE(nullptr != + strstr(output_stream.str().c_str(), "message: \"Hello\"")); + } + + { + std::stringstream output_stream; + FLAGS_metadata = "key:val\\:val"; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, + TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + // Expected output: "message: \"Hello\"" + EXPECT_TRUE(nullptr != + strstr(output_stream.str().c_str(), "message: \"Hello\"")); + } + + { + std::stringstream output_stream; + FLAGS_metadata = "key:val\\\\val"; + EXPECT_TRUE(0 == GrpcToolMainLib(ArraySize(argv), argv, + TestCliCredentials(), + std::bind(PrintStream, &output_stream, + std::placeholders::_1))); + // Expected output: "message: \"Hello\"" + EXPECT_TRUE(nullptr != + strstr(output_stream.str().c_str(), "message: \"Hello\"")); + } + + FLAGS_metadata = ""; + ShutdownServer(); +} + +TEST_F(GrpcToolTest, CallCommandWithBadMetadata) { + // Test input "grpc_cli call localhost:10000 Echo "message: 'Hello'" const char* argv[] = {"grpc_cli", "call", "localhost:10000", "grpc.testing.EchoTestService.Echo", - "message: 'Hello'"}; - FLAGS_protofiles = "src/proto/grpc/testing/echo.proto"; - char* test_srcdir = gpr_getenv("TEST_SRCDIR"); - if (test_srcdir != nullptr) { + "message: 'Hello'"}; + FLAGS_protofiles = "src/proto/grpc/testing/echo.proto"; + char* test_srcdir = gpr_getenv("TEST_SRCDIR"); + if (test_srcdir != nullptr) { FLAGS_proto_path = test_srcdir + TString("/com_github_grpc_grpc"); - } - - { - std::stringstream output_stream; - FLAGS_metadata = "key0:val0:key1"; - // Exit with 1 - EXPECT_EXIT( - GrpcToolMainLib( - ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, std::placeholders::_1)), - ::testing::ExitedWithCode(1), ".*Failed to parse metadata flag.*"); - } - - { - std::stringstream output_stream; - FLAGS_metadata = "key:val\\val"; - // Exit with 1 - EXPECT_EXIT( - GrpcToolMainLib( - ArraySize(argv), argv, TestCliCredentials(), - std::bind(PrintStream, &output_stream, std::placeholders::_1)), - ::testing::ExitedWithCode(1), ".*Failed to parse metadata flag.*"); - } - - FLAGS_metadata = ""; - FLAGS_protofiles = ""; - - gpr_free(test_srcdir); -} - + } + + { + std::stringstream output_stream; + FLAGS_metadata = "key0:val0:key1"; + // Exit with 1 + EXPECT_EXIT( + GrpcToolMainLib( + ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, std::placeholders::_1)), + ::testing::ExitedWithCode(1), ".*Failed to parse metadata flag.*"); + } + + { + std::stringstream output_stream; + FLAGS_metadata = "key:val\\val"; + // Exit with 1 + EXPECT_EXIT( + GrpcToolMainLib( + ArraySize(argv), argv, TestCliCredentials(), + std::bind(PrintStream, &output_stream, std::placeholders::_1)), + ::testing::ExitedWithCode(1), ".*Failed to parse metadata flag.*"); + } + + FLAGS_metadata = ""; + FLAGS_protofiles = ""; + + gpr_free(test_srcdir); +} + TEST_F(GrpcToolTest, ListCommand_OverrideSslHostName) { const TString server_address = SetUpServer(true); @@ -1333,12 +1333,12 @@ TEST_F(GrpcToolTest, ConfiguringDefaultServiceConfig) { ShutdownServer(); } -} // namespace testing -} // namespace grpc - -int main(int argc, char** argv) { +} // namespace testing +} // namespace grpc + +int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - ::testing::FLAGS_gtest_death_test_style = "threadsafe"; - return RUN_ALL_TESTS(); -} + ::testing::InitGoogleTest(&argc, argv); + ::testing::FLAGS_gtest_death_test_style = "threadsafe"; + return RUN_ALL_TESTS(); +} diff --git a/contrib/libs/grpc/test/cpp/util/metrics_server.cc b/contrib/libs/grpc/test/cpp/util/metrics_server.cc index 0493da053e4..ab7033689cc 100644 --- a/contrib/libs/grpc/test/cpp/util/metrics_server.cc +++ b/contrib/libs/grpc/test/cpp/util/metrics_server.cc @@ -1,117 +1,117 @@ -/* - * - * 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. - *is % allowed in string - */ - -#include "test/cpp/util/metrics_server.h" - -#include <grpc/support/log.h> -#include <grpcpp/server.h> -#include <grpcpp/server_builder.h> - -#include "src/proto/grpc/testing/metrics.grpc.pb.h" -#include "src/proto/grpc/testing/metrics.pb.h" - -namespace grpc { -namespace testing { - -QpsGauge::QpsGauge() - : start_time_(gpr_now(GPR_CLOCK_REALTIME)), num_queries_(0) {} - -void QpsGauge::Reset() { - std::lock_guard<std::mutex> lock(num_queries_mu_); - num_queries_ = 0; - start_time_ = gpr_now(GPR_CLOCK_REALTIME); -} - -void QpsGauge::Incr() { - std::lock_guard<std::mutex> lock(num_queries_mu_); - num_queries_++; -} - -long QpsGauge::Get() { - std::lock_guard<std::mutex> lock(num_queries_mu_); - gpr_timespec time_diff = - gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), start_time_); - long duration_secs = time_diff.tv_sec > 0 ? time_diff.tv_sec : 1; - return num_queries_ / duration_secs; -} - -grpc::Status MetricsServiceImpl::GetAllGauges( +/* + * + * 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. + *is % allowed in string + */ + +#include "test/cpp/util/metrics_server.h" + +#include <grpc/support/log.h> +#include <grpcpp/server.h> +#include <grpcpp/server_builder.h> + +#include "src/proto/grpc/testing/metrics.grpc.pb.h" +#include "src/proto/grpc/testing/metrics.pb.h" + +namespace grpc { +namespace testing { + +QpsGauge::QpsGauge() + : start_time_(gpr_now(GPR_CLOCK_REALTIME)), num_queries_(0) {} + +void QpsGauge::Reset() { + std::lock_guard<std::mutex> lock(num_queries_mu_); + num_queries_ = 0; + start_time_ = gpr_now(GPR_CLOCK_REALTIME); +} + +void QpsGauge::Incr() { + std::lock_guard<std::mutex> lock(num_queries_mu_); + num_queries_++; +} + +long QpsGauge::Get() { + std::lock_guard<std::mutex> lock(num_queries_mu_); + gpr_timespec time_diff = + gpr_time_sub(gpr_now(GPR_CLOCK_REALTIME), start_time_); + long duration_secs = time_diff.tv_sec > 0 ? time_diff.tv_sec : 1; + return num_queries_ / duration_secs; +} + +grpc::Status MetricsServiceImpl::GetAllGauges( ServerContext* /*context*/, const EmptyMessage* /*request*/, - ServerWriter<GaugeResponse>* writer) { - gpr_log(GPR_DEBUG, "GetAllGauges called"); - - std::lock_guard<std::mutex> lock(mu_); - for (auto it = qps_gauges_.begin(); it != qps_gauges_.end(); it++) { - GaugeResponse resp; - resp.set_name(it->first); // Gauge name - resp.set_long_value(it->second->Get()); // Gauge value - writer->Write(resp); - } - - return Status::OK; -} - + ServerWriter<GaugeResponse>* writer) { + gpr_log(GPR_DEBUG, "GetAllGauges called"); + + std::lock_guard<std::mutex> lock(mu_); + for (auto it = qps_gauges_.begin(); it != qps_gauges_.end(); it++) { + GaugeResponse resp; + resp.set_name(it->first); // Gauge name + resp.set_long_value(it->second->Get()); // Gauge value + writer->Write(resp); + } + + return Status::OK; +} + grpc::Status MetricsServiceImpl::GetGauge(ServerContext* /*context*/, - const GaugeRequest* request, - GaugeResponse* response) { - std::lock_guard<std::mutex> lock(mu_); - - const auto it = qps_gauges_.find(request->name()); - if (it != qps_gauges_.end()) { - response->set_name(it->first); - response->set_long_value(it->second->Get()); - } - - return Status::OK; -} - -std::shared_ptr<QpsGauge> MetricsServiceImpl::CreateQpsGauge( + const GaugeRequest* request, + GaugeResponse* response) { + std::lock_guard<std::mutex> lock(mu_); + + const auto it = qps_gauges_.find(request->name()); + if (it != qps_gauges_.end()) { + response->set_name(it->first); + response->set_long_value(it->second->Get()); + } + + return Status::OK; +} + +std::shared_ptr<QpsGauge> MetricsServiceImpl::CreateQpsGauge( const TString& name, bool* already_present) { - std::lock_guard<std::mutex> lock(mu_); - - std::shared_ptr<QpsGauge> qps_gauge(new QpsGauge()); - const auto p = qps_gauges_.insert(std::make_pair(name, qps_gauge)); - - // p.first is an iterator pointing to <name, shared_ptr<QpsGauge>> pair. - // p.second is a boolean which is set to 'true' if the QpsGauge is - // successfully inserted in the guages_ map and 'false' if it is already - // present in the map - *already_present = !p.second; - return p.first->second; -} - -// Starts the metrics server and returns the grpc::Server instance. Call Wait() -// on the returned server instance. -std::unique_ptr<grpc::Server> MetricsServiceImpl::StartServer(int port) { - gpr_log(GPR_INFO, "Building metrics server.."); - + std::lock_guard<std::mutex> lock(mu_); + + std::shared_ptr<QpsGauge> qps_gauge(new QpsGauge()); + const auto p = qps_gauges_.insert(std::make_pair(name, qps_gauge)); + + // p.first is an iterator pointing to <name, shared_ptr<QpsGauge>> pair. + // p.second is a boolean which is set to 'true' if the QpsGauge is + // successfully inserted in the guages_ map and 'false' if it is already + // present in the map + *already_present = !p.second; + return p.first->second; +} + +// Starts the metrics server and returns the grpc::Server instance. Call Wait() +// on the returned server instance. +std::unique_ptr<grpc::Server> MetricsServiceImpl::StartServer(int port) { + gpr_log(GPR_INFO, "Building metrics server.."); + const TString address = "0.0.0.0:" + ToString(port); - - ServerBuilder builder; - builder.AddListeningPort(address, grpc::InsecureServerCredentials()); - builder.RegisterService(this); - - std::unique_ptr<grpc::Server> server(builder.BuildAndStart()); - gpr_log(GPR_INFO, "Metrics server %s started. Ready to receive requests..", - address.c_str()); - - return server; -} - -} // namespace testing -} // namespace grpc + + ServerBuilder builder; + builder.AddListeningPort(address, grpc::InsecureServerCredentials()); + builder.RegisterService(this); + + std::unique_ptr<grpc::Server> server(builder.BuildAndStart()); + gpr_log(GPR_INFO, "Metrics server %s started. Ready to receive requests..", + address.c_str()); + + return server; +} + +} // namespace testing +} // namespace grpc diff --git a/contrib/libs/grpc/test/cpp/util/metrics_server.h b/contrib/libs/grpc/test/cpp/util/metrics_server.h index 10ffa7b4ddf..29757b6d432 100644 --- a/contrib/libs/grpc/test/cpp/util/metrics_server.h +++ b/contrib/libs/grpc/test/cpp/util/metrics_server.h @@ -1,98 +1,98 @@ -/* - * - * 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. - *is % allowed in string - */ -#ifndef GRPC_TEST_CPP_METRICS_SERVER_H -#define GRPC_TEST_CPP_METRICS_SERVER_H - -#include <map> -#include <mutex> - +/* + * + * 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. + *is % allowed in string + */ +#ifndef GRPC_TEST_CPP_METRICS_SERVER_H +#define GRPC_TEST_CPP_METRICS_SERVER_H + +#include <map> +#include <mutex> + #include <grpcpp/server.h> -#include "src/proto/grpc/testing/metrics.grpc.pb.h" -#include "src/proto/grpc/testing/metrics.pb.h" - -/* - * This implements a Metrics server defined in - * src/proto/grpc/testing/metrics.proto. Any - * test service can use this to export Metrics (TODO (sreek): Only Gauges for - * now). - * - * Example: - * MetricsServiceImpl metricsImpl; - * .. - * // Create QpsGauge(s). Note: QpsGauges can be created even after calling - * // 'StartServer'. - * QpsGauge qps_gauge1 = metricsImpl.CreateQpsGauge("foo", is_present); - * // qps_gauge1 can now be used anywhere in the program by first making a - * // one-time call qps_gauge1.Reset() and then calling qps_gauge1.Incr() - * // every time to increment a query counter - * - * ... - * // Create the metrics server - * std::unique_ptr<grpc::Server> server = metricsImpl.StartServer(port); - * server->Wait(); // Note: This is blocking. - */ -namespace grpc { -namespace testing { - -class QpsGauge { - public: - QpsGauge(); - - // Initialize the internal timer and reset the query count to 0 - void Reset(); - - // Increment the query count by 1 - void Incr(); - - // Return the current qps (i.e query count divided by the time since this - // QpsGauge object created (or Reset() was called)) - long Get(); - - private: - gpr_timespec start_time_; - long num_queries_; - std::mutex num_queries_mu_; -}; - -class MetricsServiceImpl final : public MetricsService::Service { - public: - grpc::Status GetAllGauges(ServerContext* context, const EmptyMessage* request, - ServerWriter<GaugeResponse>* writer) override; - - grpc::Status GetGauge(ServerContext* context, const GaugeRequest* request, - GaugeResponse* response) override; - - // Create a QpsGauge with name 'name'. is_present is set to true if the Gauge - // is already present in the map. - // NOTE: CreateQpsGauge can be called anytime (i.e before or after calling - // StartServer). +#include "src/proto/grpc/testing/metrics.grpc.pb.h" +#include "src/proto/grpc/testing/metrics.pb.h" + +/* + * This implements a Metrics server defined in + * src/proto/grpc/testing/metrics.proto. Any + * test service can use this to export Metrics (TODO (sreek): Only Gauges for + * now). + * + * Example: + * MetricsServiceImpl metricsImpl; + * .. + * // Create QpsGauge(s). Note: QpsGauges can be created even after calling + * // 'StartServer'. + * QpsGauge qps_gauge1 = metricsImpl.CreateQpsGauge("foo", is_present); + * // qps_gauge1 can now be used anywhere in the program by first making a + * // one-time call qps_gauge1.Reset() and then calling qps_gauge1.Incr() + * // every time to increment a query counter + * + * ... + * // Create the metrics server + * std::unique_ptr<grpc::Server> server = metricsImpl.StartServer(port); + * server->Wait(); // Note: This is blocking. + */ +namespace grpc { +namespace testing { + +class QpsGauge { + public: + QpsGauge(); + + // Initialize the internal timer and reset the query count to 0 + void Reset(); + + // Increment the query count by 1 + void Incr(); + + // Return the current qps (i.e query count divided by the time since this + // QpsGauge object created (or Reset() was called)) + long Get(); + + private: + gpr_timespec start_time_; + long num_queries_; + std::mutex num_queries_mu_; +}; + +class MetricsServiceImpl final : public MetricsService::Service { + public: + grpc::Status GetAllGauges(ServerContext* context, const EmptyMessage* request, + ServerWriter<GaugeResponse>* writer) override; + + grpc::Status GetGauge(ServerContext* context, const GaugeRequest* request, + GaugeResponse* response) override; + + // Create a QpsGauge with name 'name'. is_present is set to true if the Gauge + // is already present in the map. + // NOTE: CreateQpsGauge can be called anytime (i.e before or after calling + // StartServer). std::shared_ptr<QpsGauge> CreateQpsGauge(const TString& name, - bool* already_present); - - std::unique_ptr<grpc::Server> StartServer(int port); - - private: - std::map<string, std::shared_ptr<QpsGauge>> qps_gauges_; - std::mutex mu_; -}; - -} // namespace testing -} // namespace grpc - -#endif // GRPC_TEST_CPP_METRICS_SERVER_H + bool* already_present); + + std::unique_ptr<grpc::Server> StartServer(int port); + + private: + std::map<string, std::shared_ptr<QpsGauge>> qps_gauges_; + std::mutex mu_; +}; + +} // namespace testing +} // namespace grpc + +#endif // GRPC_TEST_CPP_METRICS_SERVER_H diff --git a/contrib/libs/grpc/test/cpp/util/proto_file_parser.cc b/contrib/libs/grpc/test/cpp/util/proto_file_parser.cc index b0912a712c6..93870b25518 100644 --- a/contrib/libs/grpc/test/cpp/util/proto_file_parser.cc +++ b/contrib/libs/grpc/test/cpp/util/proto_file_parser.cc @@ -1,257 +1,257 @@ -/* - * - * Copyright 2016 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 "test/cpp/util/proto_file_parser.h" - -#include <algorithm> -#include <iostream> -#include <sstream> -#include <unordered_set> - -#include <grpcpp/support/config.h> - -namespace grpc { -namespace testing { -namespace { - -// Match the user input method string to the full_name from method descriptor. +/* + * + * Copyright 2016 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 "test/cpp/util/proto_file_parser.h" + +#include <algorithm> +#include <iostream> +#include <sstream> +#include <unordered_set> + +#include <grpcpp/support/config.h> + +namespace grpc { +namespace testing { +namespace { + +// Match the user input method string to the full_name from method descriptor. bool MethodNameMatch(const TString& full_name, const TString& input) { TString clean_input = input; std::replace(clean_input.begin(), clean_input.vend(), '/', '.'); - if (clean_input.size() > full_name.size()) { - return false; - } - return full_name.compare(full_name.size() - clean_input.size(), - clean_input.size(), clean_input) == 0; -} -} // namespace - -class ErrorPrinter : public protobuf::compiler::MultiFileErrorCollector { - public: - explicit ErrorPrinter(ProtoFileParser* parser) : parser_(parser) {} - - void AddError(const google::protobuf::string& filename, int line, int column, - const google::protobuf::string& message) override { - std::ostringstream oss; - oss << "error " << filename << " " << line << " " << column << " " - << message << "\n"; - parser_->LogError(oss.str()); - } - - void AddWarning(const google::protobuf::string& filename, int line, int column, - const google::protobuf::string& message) override { - std::cerr << "warning " << filename << " " << line << " " << column << " " - << message << std::endl; - } - - private: - ProtoFileParser* parser_; // not owned -}; - + if (clean_input.size() > full_name.size()) { + return false; + } + return full_name.compare(full_name.size() - clean_input.size(), + clean_input.size(), clean_input) == 0; +} +} // namespace + +class ErrorPrinter : public protobuf::compiler::MultiFileErrorCollector { + public: + explicit ErrorPrinter(ProtoFileParser* parser) : parser_(parser) {} + + void AddError(const google::protobuf::string& filename, int line, int column, + const google::protobuf::string& message) override { + std::ostringstream oss; + oss << "error " << filename << " " << line << " " << column << " " + << message << "\n"; + parser_->LogError(oss.str()); + } + + void AddWarning(const google::protobuf::string& filename, int line, int column, + const google::protobuf::string& message) override { + std::cerr << "warning " << filename << " " << line << " " << column << " " + << message << std::endl; + } + + private: + ProtoFileParser* parser_; // not owned +}; + ProtoFileParser::ProtoFileParser(const std::shared_ptr<grpc::Channel>& channel, const TString& proto_path, const TString& protofiles) - : has_error_(false), - dynamic_factory_(new protobuf::DynamicMessageFactory()) { + : has_error_(false), + dynamic_factory_(new protobuf::DynamicMessageFactory()) { std::vector<TString> service_list; - if (channel) { - reflection_db_.reset(new grpc::ProtoReflectionDescriptorDatabase(channel)); - reflection_db_->GetServices(&service_list); - } - + if (channel) { + reflection_db_.reset(new grpc::ProtoReflectionDescriptorDatabase(channel)); + reflection_db_->GetServices(&service_list); + } + std::unordered_set<TString> known_services; - if (!protofiles.empty()) { - source_tree_.MapPath("", google::protobuf::string(proto_path)); - error_printer_.reset(new ErrorPrinter(this)); - importer_.reset( - new protobuf::compiler::Importer(&source_tree_, error_printer_.get())); - + if (!protofiles.empty()) { + source_tree_.MapPath("", google::protobuf::string(proto_path)); + error_printer_.reset(new ErrorPrinter(this)); + importer_.reset( + new protobuf::compiler::Importer(&source_tree_, error_printer_.get())); + std::string file_name; - std::stringstream ss(protofiles); - while (std::getline(ss, file_name, ',')) { + std::stringstream ss(protofiles); + while (std::getline(ss, file_name, ',')) { const auto* file_desc = importer_->Import(google::protobuf::string(file_name.c_str())); - if (file_desc) { - for (int i = 0; i < file_desc->service_count(); i++) { - service_desc_list_.push_back(file_desc->service(i)); - known_services.insert(file_desc->service(i)->full_name()); - } - } else { - std::cerr << file_name << " not found" << std::endl; - } - } - - file_db_.reset(new protobuf::DescriptorPoolDatabase(*importer_->pool())); - } - - if (!reflection_db_ && !file_db_) { - LogError("No available proto database"); - return; - } - - if (!reflection_db_) { - desc_db_ = std::move(file_db_); - } else if (!file_db_) { - desc_db_ = std::move(reflection_db_); - } else { - desc_db_.reset(new protobuf::MergedDescriptorDatabase(reflection_db_.get(), - file_db_.get())); - } - - desc_pool_.reset(new protobuf::DescriptorPool(desc_db_.get())); - - for (auto it = service_list.begin(); it != service_list.end(); it++) { - if (known_services.find(*it) == known_services.end()) { - if (const protobuf::ServiceDescriptor* service_desc = - desc_pool_->FindServiceByName(google::protobuf::string(*it))) { - service_desc_list_.push_back(service_desc); - known_services.insert(*it); - } - } - } -} - -ProtoFileParser::~ProtoFileParser() {} - + if (file_desc) { + for (int i = 0; i < file_desc->service_count(); i++) { + service_desc_list_.push_back(file_desc->service(i)); + known_services.insert(file_desc->service(i)->full_name()); + } + } else { + std::cerr << file_name << " not found" << std::endl; + } + } + + file_db_.reset(new protobuf::DescriptorPoolDatabase(*importer_->pool())); + } + + if (!reflection_db_ && !file_db_) { + LogError("No available proto database"); + return; + } + + if (!reflection_db_) { + desc_db_ = std::move(file_db_); + } else if (!file_db_) { + desc_db_ = std::move(reflection_db_); + } else { + desc_db_.reset(new protobuf::MergedDescriptorDatabase(reflection_db_.get(), + file_db_.get())); + } + + desc_pool_.reset(new protobuf::DescriptorPool(desc_db_.get())); + + for (auto it = service_list.begin(); it != service_list.end(); it++) { + if (known_services.find(*it) == known_services.end()) { + if (const protobuf::ServiceDescriptor* service_desc = + desc_pool_->FindServiceByName(google::protobuf::string(*it))) { + service_desc_list_.push_back(service_desc); + known_services.insert(*it); + } + } + } +} + +ProtoFileParser::~ProtoFileParser() {} + TString ProtoFileParser::GetFullMethodName(const TString& method) { - has_error_ = false; - - if (known_methods_.find(method) != known_methods_.end()) { - return known_methods_[method]; - } - - const protobuf::MethodDescriptor* method_descriptor = nullptr; - for (auto it = service_desc_list_.begin(); it != service_desc_list_.end(); - it++) { - const auto* service_desc = *it; - for (int j = 0; j < service_desc->method_count(); j++) { - const auto* method_desc = service_desc->method(j); - if (MethodNameMatch(method_desc->full_name(), method)) { - if (method_descriptor) { - std::ostringstream error_stream; - error_stream << "Ambiguous method names: "; - error_stream << method_descriptor->full_name() << " "; - error_stream << method_desc->full_name(); - LogError(error_stream.str()); - } - method_descriptor = method_desc; - } - } - } - if (!method_descriptor) { - LogError("Method name not found"); - } - if (has_error_) { - return ""; - } - - known_methods_[method] = method_descriptor->full_name(); - - return method_descriptor->full_name(); -} - + has_error_ = false; + + if (known_methods_.find(method) != known_methods_.end()) { + return known_methods_[method]; + } + + const protobuf::MethodDescriptor* method_descriptor = nullptr; + for (auto it = service_desc_list_.begin(); it != service_desc_list_.end(); + it++) { + const auto* service_desc = *it; + for (int j = 0; j < service_desc->method_count(); j++) { + const auto* method_desc = service_desc->method(j); + if (MethodNameMatch(method_desc->full_name(), method)) { + if (method_descriptor) { + std::ostringstream error_stream; + error_stream << "Ambiguous method names: "; + error_stream << method_descriptor->full_name() << " "; + error_stream << method_desc->full_name(); + LogError(error_stream.str()); + } + method_descriptor = method_desc; + } + } + } + if (!method_descriptor) { + LogError("Method name not found"); + } + if (has_error_) { + return ""; + } + + known_methods_[method] = method_descriptor->full_name(); + + return method_descriptor->full_name(); +} + TString ProtoFileParser::GetFormattedMethodName(const TString& method) { - has_error_ = false; + has_error_ = false; TString formatted_method_name = GetFullMethodName(method); - if (has_error_) { - return ""; - } - size_t last_dot = formatted_method_name.find_last_of('.'); + if (has_error_) { + return ""; + } + size_t last_dot = formatted_method_name.find_last_of('.'); if (last_dot != TString::npos) { - formatted_method_name[last_dot] = '/'; - } - formatted_method_name.insert(formatted_method_name.begin(), '/'); - return formatted_method_name; -} - + formatted_method_name[last_dot] = '/'; + } + formatted_method_name.insert(formatted_method_name.begin(), '/'); + return formatted_method_name; +} + TString ProtoFileParser::GetMessageTypeFromMethod(const TString& method, bool is_request) { - has_error_ = false; + has_error_ = false; TString full_method_name = GetFullMethodName(method); - if (has_error_) { - return ""; - } - const protobuf::MethodDescriptor* method_desc = - desc_pool_->FindMethodByName(google::protobuf::string(full_method_name)); - if (!method_desc) { - LogError("Method not found"); - return ""; - } - - return is_request ? method_desc->input_type()->full_name() - : method_desc->output_type()->full_name(); -} - + if (has_error_) { + return ""; + } + const protobuf::MethodDescriptor* method_desc = + desc_pool_->FindMethodByName(google::protobuf::string(full_method_name)); + if (!method_desc) { + LogError("Method not found"); + return ""; + } + + return is_request ? method_desc->input_type()->full_name() + : method_desc->output_type()->full_name(); +} + bool ProtoFileParser::IsStreaming(const TString& method, bool is_request) { - has_error_ = false; - + has_error_ = false; + TString full_method_name = GetFullMethodName(method); - if (has_error_) { - return false; - } - - const protobuf::MethodDescriptor* method_desc = - desc_pool_->FindMethodByName(google::protobuf::string(full_method_name)); - if (!method_desc) { - LogError("Method not found"); - return false; - } - - return is_request ? method_desc->client_streaming() - : method_desc->server_streaming(); -} - + if (has_error_) { + return false; + } + + const protobuf::MethodDescriptor* method_desc = + desc_pool_->FindMethodByName(google::protobuf::string(full_method_name)); + if (!method_desc) { + LogError("Method not found"); + return false; + } + + return is_request ? method_desc->client_streaming() + : method_desc->server_streaming(); +} + TString ProtoFileParser::GetSerializedProtoFromMethod( const TString& method, const TString& formatted_proto, bool is_request, bool is_json_format) { - has_error_ = false; + has_error_ = false; TString message_type_name = GetMessageTypeFromMethod(method, is_request); - if (has_error_) { - return ""; - } + if (has_error_) { + return ""; + } return GetSerializedProtoFromMessageType(message_type_name, formatted_proto, is_json_format); -} - +} + TString ProtoFileParser::GetFormattedStringFromMethod( const TString& method, const TString& serialized_proto, bool is_request, bool is_json_format) { - has_error_ = false; + has_error_ = false; TString message_type_name = GetMessageTypeFromMethod(method, is_request); - if (has_error_) { - return ""; - } + if (has_error_) { + return ""; + } return GetFormattedStringFromMessageType(message_type_name, serialized_proto, is_json_format); -} - +} + TString ProtoFileParser::GetSerializedProtoFromMessageType( const TString& message_type_name, const TString& formatted_proto, bool is_json_format) { - has_error_ = false; - google::protobuf::string serialized; - const protobuf::Descriptor* desc = - desc_pool_->FindMessageTypeByName(google::protobuf::string(message_type_name)); - if (!desc) { - LogError("Message type not found"); - return ""; - } - std::unique_ptr<grpc::protobuf::Message> msg( - dynamic_factory_->GetPrototype(desc)->New()); + has_error_ = false; + google::protobuf::string serialized; + const protobuf::Descriptor* desc = + desc_pool_->FindMessageTypeByName(google::protobuf::string(message_type_name)); + if (!desc) { + LogError("Message type not found"); + return ""; + } + std::unique_ptr<grpc::protobuf::Message> msg( + dynamic_factory_->GetPrototype(desc)->New()); bool ok; if (is_json_format) { ok = grpc::protobuf::json::JsonStringToMessage(google::protobuf::string(formatted_proto), msg.get()) @@ -266,32 +266,32 @@ TString ProtoFileParser::GetSerializedProtoFromMessageType( LogError("Failed to convert text format to proto."); return ""; } - } - - ok = msg->SerializeToString(&serialized); - if (!ok) { - LogError("Failed to serialize proto."); - return ""; - } - return serialized; -} - + } + + ok = msg->SerializeToString(&serialized); + if (!ok) { + LogError("Failed to serialize proto."); + return ""; + } + return serialized; +} + TString ProtoFileParser::GetFormattedStringFromMessageType( const TString& message_type_name, const TString& serialized_proto, bool is_json_format) { - has_error_ = false; - const protobuf::Descriptor* desc = - desc_pool_->FindMessageTypeByName(google::protobuf::string(message_type_name)); - if (!desc) { - LogError("Message type not found"); - return ""; - } - std::unique_ptr<grpc::protobuf::Message> msg( - dynamic_factory_->GetPrototype(desc)->New()); - if (!msg->ParseFromString(google::protobuf::string(serialized_proto))) { - LogError("Failed to deserialize proto."); - return ""; - } + has_error_ = false; + const protobuf::Descriptor* desc = + desc_pool_->FindMessageTypeByName(google::protobuf::string(message_type_name)); + if (!desc) { + LogError("Message type not found"); + return ""; + } + std::unique_ptr<grpc::protobuf::Message> msg( + dynamic_factory_->GetPrototype(desc)->New()); + if (!msg->ParseFromString(google::protobuf::string(serialized_proto))) { + LogError("Failed to deserialize proto."); + return ""; + } google::protobuf::string formatted_string; if (is_json_format) { @@ -308,16 +308,16 @@ TString ProtoFileParser::GetFormattedStringFromMessageType( LogError("Failed to print proto message to text format"); return ""; } - } + } return formatted_string; -} - +} + void ProtoFileParser::LogError(const TString& error_msg) { - if (!error_msg.empty()) { - std::cerr << error_msg << std::endl; - } - has_error_ = true; -} - -} // namespace testing -} // namespace grpc + if (!error_msg.empty()) { + std::cerr << error_msg << std::endl; + } + has_error_ = true; +} + +} // namespace testing +} // namespace grpc diff --git a/contrib/libs/grpc/test/cpp/util/proto_file_parser.h b/contrib/libs/grpc/test/cpp/util/proto_file_parser.h index c0445641c73..79b0c8e3597 100644 --- a/contrib/libs/grpc/test/cpp/util/proto_file_parser.h +++ b/contrib/libs/grpc/test/cpp/util/proto_file_parser.h @@ -1,57 +1,57 @@ -/* - * - * Copyright 2016 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. - * - */ - -#ifndef GRPC_TEST_CPP_UTIL_PROTO_FILE_PARSER_H -#define GRPC_TEST_CPP_UTIL_PROTO_FILE_PARSER_H - -#include <memory> - -#include <grpcpp/channel.h> - -#include "test/cpp/util/config_grpc_cli.h" -#include "test/cpp/util/proto_reflection_descriptor_database.h" - -namespace grpc { -namespace testing { -class ErrorPrinter; - -// Find method and associated request/response types. -class ProtoFileParser { - public: - // The parser will search proto files using the server reflection service - // provided on the given channel. The given protofiles in a source tree rooted - // from proto_path will also be searched. +/* + * + * Copyright 2016 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. + * + */ + +#ifndef GRPC_TEST_CPP_UTIL_PROTO_FILE_PARSER_H +#define GRPC_TEST_CPP_UTIL_PROTO_FILE_PARSER_H + +#include <memory> + +#include <grpcpp/channel.h> + +#include "test/cpp/util/config_grpc_cli.h" +#include "test/cpp/util/proto_reflection_descriptor_database.h" + +namespace grpc { +namespace testing { +class ErrorPrinter; + +// Find method and associated request/response types. +class ProtoFileParser { + public: + // The parser will search proto files using the server reflection service + // provided on the given channel. The given protofiles in a source tree rooted + // from proto_path will also be searched. ProtoFileParser(const std::shared_ptr<grpc::Channel>& channel, const TString& proto_path, const TString& protofiles); - - ~ProtoFileParser(); - - // The input method name in the following four functions could be a partial - // string such as Service.Method or even just Method. It will log an error if - // there is ambiguity. - // Full method name is in the form of Service.Method, it's good to be used in - // descriptor database queries. + + ~ProtoFileParser(); + + // The input method name in the following four functions could be a partial + // string such as Service.Method or even just Method. It will log an error if + // there is ambiguity. + // Full method name is in the form of Service.Method, it's good to be used in + // descriptor database queries. TString GetFullMethodName(const TString& method); - - // Formatted method name is in the form of /Service/Method, it's good to be - // used as the argument of Stub::Call() + + // Formatted method name is in the form of /Service/Method, it's good to be + // used as the argument of Stub::Call() TString GetFormattedMethodName(const TString& method); - + /// Converts a text or json string to its binary proto representation for the /// given method's input or return type. /// \param method the name of the method (does not need to be fully qualified @@ -67,7 +67,7 @@ class ProtoFileParser { const TString& formatted_proto, bool is_request, bool is_json_format); - + /// Converts a text or json string to its proto representation for the given /// message type. /// \param formatted_proto the text- or json-formatted proto string @@ -75,7 +75,7 @@ class ProtoFileParser { TString GetSerializedProtoFromMessageType( const TString& message_type_name, const TString& formatted_proto, bool is_json_format); - + /// Converts a binary proto string to its text or json string representation /// for the given method's input or return type. /// \param method the name of the method (does not need to be a fully @@ -96,34 +96,34 @@ class ProtoFileParser { TString GetFormattedStringFromMessageType( const TString& message_type_name, const TString& serialized_proto, bool is_json_format); - + bool IsStreaming(const TString& method, bool is_request); - - bool HasError() const { return has_error_; } - + + bool HasError() const { return has_error_; } + void LogError(const TString& error_msg); - - private: + + private: TString GetMessageTypeFromMethod(const TString& method, bool is_request); - - bool has_error_; + + bool has_error_; TString request_text_; - protobuf::compiler::DiskSourceTree source_tree_; - std::unique_ptr<ErrorPrinter> error_printer_; - std::unique_ptr<protobuf::compiler::Importer> importer_; - std::unique_ptr<grpc::ProtoReflectionDescriptorDatabase> reflection_db_; - std::unique_ptr<protobuf::DescriptorPoolDatabase> file_db_; - std::unique_ptr<protobuf::DescriptorDatabase> desc_db_; - std::unique_ptr<protobuf::DescriptorPool> desc_pool_; - std::unique_ptr<protobuf::DynamicMessageFactory> dynamic_factory_; - std::unique_ptr<grpc::protobuf::Message> request_prototype_; - std::unique_ptr<grpc::protobuf::Message> response_prototype_; + protobuf::compiler::DiskSourceTree source_tree_; + std::unique_ptr<ErrorPrinter> error_printer_; + std::unique_ptr<protobuf::compiler::Importer> importer_; + std::unique_ptr<grpc::ProtoReflectionDescriptorDatabase> reflection_db_; + std::unique_ptr<protobuf::DescriptorPoolDatabase> file_db_; + std::unique_ptr<protobuf::DescriptorDatabase> desc_db_; + std::unique_ptr<protobuf::DescriptorPool> desc_pool_; + std::unique_ptr<protobuf::DynamicMessageFactory> dynamic_factory_; + std::unique_ptr<grpc::protobuf::Message> request_prototype_; + std::unique_ptr<grpc::protobuf::Message> response_prototype_; std::unordered_map<TString, TString> known_methods_; - std::vector<const protobuf::ServiceDescriptor*> service_desc_list_; -}; - -} // namespace testing -} // namespace grpc - -#endif // GRPC_TEST_CPP_UTIL_PROTO_FILE_PARSER_H + std::vector<const protobuf::ServiceDescriptor*> service_desc_list_; +}; + +} // namespace testing +} // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_PROTO_FILE_PARSER_H diff --git a/contrib/libs/grpc/test/cpp/util/proto_reflection_descriptor_database.cc b/contrib/libs/grpc/test/cpp/util/proto_reflection_descriptor_database.cc index 27a4c1e4cf8..320c0accfed 100644 --- a/contrib/libs/grpc/test/cpp/util/proto_reflection_descriptor_database.cc +++ b/contrib/libs/grpc/test/cpp/util/proto_reflection_descriptor_database.cc @@ -1,51 +1,51 @@ -/* - * - * Copyright 2016 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 "test/cpp/util/proto_reflection_descriptor_database.h" - -#include <vector> - -#include <grpc/support/log.h> - -using grpc::reflection::v1alpha::ErrorResponse; -using grpc::reflection::v1alpha::ListServiceResponse; -using grpc::reflection::v1alpha::ServerReflection; -using grpc::reflection::v1alpha::ServerReflectionRequest; -using grpc::reflection::v1alpha::ServerReflectionResponse; - -namespace grpc { - -ProtoReflectionDescriptorDatabase::ProtoReflectionDescriptorDatabase( - std::unique_ptr<ServerReflection::Stub> stub) - : stub_(std::move(stub)) {} - -ProtoReflectionDescriptorDatabase::ProtoReflectionDescriptorDatabase( +/* + * + * Copyright 2016 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 "test/cpp/util/proto_reflection_descriptor_database.h" + +#include <vector> + +#include <grpc/support/log.h> + +using grpc::reflection::v1alpha::ErrorResponse; +using grpc::reflection::v1alpha::ListServiceResponse; +using grpc::reflection::v1alpha::ServerReflection; +using grpc::reflection::v1alpha::ServerReflectionRequest; +using grpc::reflection::v1alpha::ServerReflectionResponse; + +namespace grpc { + +ProtoReflectionDescriptorDatabase::ProtoReflectionDescriptorDatabase( + std::unique_ptr<ServerReflection::Stub> stub) + : stub_(std::move(stub)) {} + +ProtoReflectionDescriptorDatabase::ProtoReflectionDescriptorDatabase( const std::shared_ptr<grpc::Channel>& channel) - : stub_(ServerReflection::NewStub(channel)) {} - -ProtoReflectionDescriptorDatabase::~ProtoReflectionDescriptorDatabase() { - if (stream_) { - stream_->WritesDone(); - Status status = stream_->Finish(); - if (!status.ok()) { - if (status.error_code() == StatusCode::UNIMPLEMENTED) { + : stub_(ServerReflection::NewStub(channel)) {} + +ProtoReflectionDescriptorDatabase::~ProtoReflectionDescriptorDatabase() { + if (stream_) { + stream_->WritesDone(); + Status status = stream_->Finish(); + if (!status.ok()) { + if (status.error_code() == StatusCode::UNIMPLEMENTED) { fprintf(stderr, - "Reflection request not implemented; " + "Reflection request not implemented; " "is the ServerReflection service enabled?\n"); } else { fprintf(stderr, @@ -54,280 +54,280 @@ ProtoReflectionDescriptorDatabase::~ProtoReflectionDescriptorDatabase() { static_cast<int>(status.error_code()), status.error_message().c_str(), ctx_.debug_error_string().c_str()); - } - } - } -} - -bool ProtoReflectionDescriptorDatabase::FindFileByName( - const google::protobuf::string& filename, protobuf::FileDescriptorProto* output) { - if (cached_db_.FindFileByName(filename, output)) { - return true; - } - - if (known_files_.find(filename) != known_files_.end()) { - return false; - } - - ServerReflectionRequest request; - request.set_file_by_filename(filename); - ServerReflectionResponse response; - - if (!DoOneRequest(request, response)) { - return false; - } - - if (response.message_response_case() == - ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse) { - AddFileFromResponse(response.file_descriptor_response()); - } else if (response.message_response_case() == - ServerReflectionResponse::MessageResponseCase::kErrorResponse) { + } + } + } +} + +bool ProtoReflectionDescriptorDatabase::FindFileByName( + const google::protobuf::string& filename, protobuf::FileDescriptorProto* output) { + if (cached_db_.FindFileByName(filename, output)) { + return true; + } + + if (known_files_.find(filename) != known_files_.end()) { + return false; + } + + ServerReflectionRequest request; + request.set_file_by_filename(filename); + ServerReflectionResponse response; + + if (!DoOneRequest(request, response)) { + return false; + } + + if (response.message_response_case() == + ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse) { + AddFileFromResponse(response.file_descriptor_response()); + } else if (response.message_response_case() == + ServerReflectionResponse::MessageResponseCase::kErrorResponse) { const ErrorResponse& error = response.error_response(); - if (error.error_code() == StatusCode::NOT_FOUND) { - gpr_log(GPR_INFO, "NOT_FOUND from server for FindFileByName(%s)", - filename.c_str()); - } else { - gpr_log(GPR_INFO, - "Error on FindFileByName(%s)\n\tError code: %d\n" - "\tError Message: %s", - filename.c_str(), error.error_code(), - error.error_message().c_str()); - } - } else { - gpr_log( - GPR_INFO, - "Error on FindFileByName(%s) response type\n" - "\tExpecting: %d\n\tReceived: %d", - filename.c_str(), - ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse, - response.message_response_case()); - } - - return cached_db_.FindFileByName(filename, output); -} - -bool ProtoReflectionDescriptorDatabase::FindFileContainingSymbol( - const google::protobuf::string& symbol_name, protobuf::FileDescriptorProto* output) { - if (cached_db_.FindFileContainingSymbol(symbol_name, output)) { - return true; - } - - if (missing_symbols_.find(symbol_name) != missing_symbols_.end()) { - return false; - } - - ServerReflectionRequest request; - request.set_file_containing_symbol(symbol_name); - ServerReflectionResponse response; - - if (!DoOneRequest(request, response)) { - return false; - } - - if (response.message_response_case() == - ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse) { - AddFileFromResponse(response.file_descriptor_response()); - } else if (response.message_response_case() == - ServerReflectionResponse::MessageResponseCase::kErrorResponse) { + if (error.error_code() == StatusCode::NOT_FOUND) { + gpr_log(GPR_INFO, "NOT_FOUND from server for FindFileByName(%s)", + filename.c_str()); + } else { + gpr_log(GPR_INFO, + "Error on FindFileByName(%s)\n\tError code: %d\n" + "\tError Message: %s", + filename.c_str(), error.error_code(), + error.error_message().c_str()); + } + } else { + gpr_log( + GPR_INFO, + "Error on FindFileByName(%s) response type\n" + "\tExpecting: %d\n\tReceived: %d", + filename.c_str(), + ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse, + response.message_response_case()); + } + + return cached_db_.FindFileByName(filename, output); +} + +bool ProtoReflectionDescriptorDatabase::FindFileContainingSymbol( + const google::protobuf::string& symbol_name, protobuf::FileDescriptorProto* output) { + if (cached_db_.FindFileContainingSymbol(symbol_name, output)) { + return true; + } + + if (missing_symbols_.find(symbol_name) != missing_symbols_.end()) { + return false; + } + + ServerReflectionRequest request; + request.set_file_containing_symbol(symbol_name); + ServerReflectionResponse response; + + if (!DoOneRequest(request, response)) { + return false; + } + + if (response.message_response_case() == + ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse) { + AddFileFromResponse(response.file_descriptor_response()); + } else if (response.message_response_case() == + ServerReflectionResponse::MessageResponseCase::kErrorResponse) { const ErrorResponse& error = response.error_response(); - if (error.error_code() == StatusCode::NOT_FOUND) { - missing_symbols_.insert(symbol_name); - gpr_log(GPR_INFO, - "NOT_FOUND from server for FindFileContainingSymbol(%s)", - symbol_name.c_str()); - } else { - gpr_log(GPR_INFO, - "Error on FindFileContainingSymbol(%s)\n" - "\tError code: %d\n\tError Message: %s", - symbol_name.c_str(), error.error_code(), - error.error_message().c_str()); - } - } else { - gpr_log( - GPR_INFO, - "Error on FindFileContainingSymbol(%s) response type\n" - "\tExpecting: %d\n\tReceived: %d", - symbol_name.c_str(), - ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse, - response.message_response_case()); - } - return cached_db_.FindFileContainingSymbol(symbol_name, output); -} - -bool ProtoReflectionDescriptorDatabase::FindFileContainingExtension( - const google::protobuf::string& containing_type, int field_number, - protobuf::FileDescriptorProto* output) { - if (cached_db_.FindFileContainingExtension(containing_type, field_number, - output)) { - return true; - } - - if (missing_extensions_.find(containing_type) != missing_extensions_.end() && - missing_extensions_[containing_type].find(field_number) != - missing_extensions_[containing_type].end()) { - gpr_log(GPR_INFO, "nested map."); - return false; - } - - ServerReflectionRequest request; - request.mutable_file_containing_extension()->set_containing_type( - containing_type); - request.mutable_file_containing_extension()->set_extension_number( - field_number); - ServerReflectionResponse response; - - if (!DoOneRequest(request, response)) { - return false; - } - - if (response.message_response_case() == - ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse) { - AddFileFromResponse(response.file_descriptor_response()); - } else if (response.message_response_case() == - ServerReflectionResponse::MessageResponseCase::kErrorResponse) { + if (error.error_code() == StatusCode::NOT_FOUND) { + missing_symbols_.insert(symbol_name); + gpr_log(GPR_INFO, + "NOT_FOUND from server for FindFileContainingSymbol(%s)", + symbol_name.c_str()); + } else { + gpr_log(GPR_INFO, + "Error on FindFileContainingSymbol(%s)\n" + "\tError code: %d\n\tError Message: %s", + symbol_name.c_str(), error.error_code(), + error.error_message().c_str()); + } + } else { + gpr_log( + GPR_INFO, + "Error on FindFileContainingSymbol(%s) response type\n" + "\tExpecting: %d\n\tReceived: %d", + symbol_name.c_str(), + ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse, + response.message_response_case()); + } + return cached_db_.FindFileContainingSymbol(symbol_name, output); +} + +bool ProtoReflectionDescriptorDatabase::FindFileContainingExtension( + const google::protobuf::string& containing_type, int field_number, + protobuf::FileDescriptorProto* output) { + if (cached_db_.FindFileContainingExtension(containing_type, field_number, + output)) { + return true; + } + + if (missing_extensions_.find(containing_type) != missing_extensions_.end() && + missing_extensions_[containing_type].find(field_number) != + missing_extensions_[containing_type].end()) { + gpr_log(GPR_INFO, "nested map."); + return false; + } + + ServerReflectionRequest request; + request.mutable_file_containing_extension()->set_containing_type( + containing_type); + request.mutable_file_containing_extension()->set_extension_number( + field_number); + ServerReflectionResponse response; + + if (!DoOneRequest(request, response)) { + return false; + } + + if (response.message_response_case() == + ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse) { + AddFileFromResponse(response.file_descriptor_response()); + } else if (response.message_response_case() == + ServerReflectionResponse::MessageResponseCase::kErrorResponse) { const ErrorResponse& error = response.error_response(); - if (error.error_code() == StatusCode::NOT_FOUND) { - if (missing_extensions_.find(containing_type) == - missing_extensions_.end()) { - missing_extensions_[containing_type] = {}; - } - missing_extensions_[containing_type].insert(field_number); - gpr_log(GPR_INFO, - "NOT_FOUND from server for FindFileContainingExtension(%s, %d)", - containing_type.c_str(), field_number); - } else { - gpr_log(GPR_INFO, - "Error on FindFileContainingExtension(%s, %d)\n" - "\tError code: %d\n\tError Message: %s", - containing_type.c_str(), field_number, error.error_code(), - error.error_message().c_str()); - } - } else { - gpr_log( - GPR_INFO, - "Error on FindFileContainingExtension(%s, %d) response type\n" - "\tExpecting: %d\n\tReceived: %d", - containing_type.c_str(), field_number, - ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse, - response.message_response_case()); - } - - return cached_db_.FindFileContainingExtension(containing_type, field_number, - output); -} - -bool ProtoReflectionDescriptorDatabase::FindAllExtensionNumbers( - const google::protobuf::string& extendee_type, std::vector<int>* output) { - if (cached_extension_numbers_.find(extendee_type) != - cached_extension_numbers_.end()) { - *output = cached_extension_numbers_[extendee_type]; - return true; - } - - ServerReflectionRequest request; - request.set_all_extension_numbers_of_type(extendee_type); - ServerReflectionResponse response; - - if (!DoOneRequest(request, response)) { - return false; - } - - if (response.message_response_case() == - ServerReflectionResponse::MessageResponseCase:: - kAllExtensionNumbersResponse) { - auto number = response.all_extension_numbers_response().extension_number(); - *output = std::vector<int>(number.begin(), number.end()); - cached_extension_numbers_[extendee_type] = *output; - return true; - } else if (response.message_response_case() == - ServerReflectionResponse::MessageResponseCase::kErrorResponse) { + if (error.error_code() == StatusCode::NOT_FOUND) { + if (missing_extensions_.find(containing_type) == + missing_extensions_.end()) { + missing_extensions_[containing_type] = {}; + } + missing_extensions_[containing_type].insert(field_number); + gpr_log(GPR_INFO, + "NOT_FOUND from server for FindFileContainingExtension(%s, %d)", + containing_type.c_str(), field_number); + } else { + gpr_log(GPR_INFO, + "Error on FindFileContainingExtension(%s, %d)\n" + "\tError code: %d\n\tError Message: %s", + containing_type.c_str(), field_number, error.error_code(), + error.error_message().c_str()); + } + } else { + gpr_log( + GPR_INFO, + "Error on FindFileContainingExtension(%s, %d) response type\n" + "\tExpecting: %d\n\tReceived: %d", + containing_type.c_str(), field_number, + ServerReflectionResponse::MessageResponseCase::kFileDescriptorResponse, + response.message_response_case()); + } + + return cached_db_.FindFileContainingExtension(containing_type, field_number, + output); +} + +bool ProtoReflectionDescriptorDatabase::FindAllExtensionNumbers( + const google::protobuf::string& extendee_type, std::vector<int>* output) { + if (cached_extension_numbers_.find(extendee_type) != + cached_extension_numbers_.end()) { + *output = cached_extension_numbers_[extendee_type]; + return true; + } + + ServerReflectionRequest request; + request.set_all_extension_numbers_of_type(extendee_type); + ServerReflectionResponse response; + + if (!DoOneRequest(request, response)) { + return false; + } + + if (response.message_response_case() == + ServerReflectionResponse::MessageResponseCase:: + kAllExtensionNumbersResponse) { + auto number = response.all_extension_numbers_response().extension_number(); + *output = std::vector<int>(number.begin(), number.end()); + cached_extension_numbers_[extendee_type] = *output; + return true; + } else if (response.message_response_case() == + ServerReflectionResponse::MessageResponseCase::kErrorResponse) { const ErrorResponse& error = response.error_response(); - if (error.error_code() == StatusCode::NOT_FOUND) { - gpr_log(GPR_INFO, "NOT_FOUND from server for FindAllExtensionNumbers(%s)", - extendee_type.c_str()); - } else { - gpr_log(GPR_INFO, - "Error on FindAllExtensionNumbersExtension(%s)\n" - "\tError code: %d\n\tError Message: %s", - extendee_type.c_str(), error.error_code(), - error.error_message().c_str()); - } - } - return false; -} - -bool ProtoReflectionDescriptorDatabase::GetServices( + if (error.error_code() == StatusCode::NOT_FOUND) { + gpr_log(GPR_INFO, "NOT_FOUND from server for FindAllExtensionNumbers(%s)", + extendee_type.c_str()); + } else { + gpr_log(GPR_INFO, + "Error on FindAllExtensionNumbersExtension(%s)\n" + "\tError code: %d\n\tError Message: %s", + extendee_type.c_str(), error.error_code(), + error.error_message().c_str()); + } + } + return false; +} + +bool ProtoReflectionDescriptorDatabase::GetServices( std::vector<TString>* output) { - ServerReflectionRequest request; - request.set_list_services(""); - ServerReflectionResponse response; - - if (!DoOneRequest(request, response)) { - return false; - } - - if (response.message_response_case() == - ServerReflectionResponse::MessageResponseCase::kListServicesResponse) { + ServerReflectionRequest request; + request.set_list_services(""); + ServerReflectionResponse response; + + if (!DoOneRequest(request, response)) { + return false; + } + + if (response.message_response_case() == + ServerReflectionResponse::MessageResponseCase::kListServicesResponse) { const ListServiceResponse& ls_response = response.list_services_response(); - for (int i = 0; i < ls_response.service_size(); ++i) { - (*output).push_back(ls_response.service(i).name()); - } - return true; - } else if (response.message_response_case() == - ServerReflectionResponse::MessageResponseCase::kErrorResponse) { + for (int i = 0; i < ls_response.service_size(); ++i) { + (*output).push_back(ls_response.service(i).name()); + } + return true; + } else if (response.message_response_case() == + ServerReflectionResponse::MessageResponseCase::kErrorResponse) { const ErrorResponse& error = response.error_response(); - gpr_log(GPR_INFO, - "Error on GetServices()\n\tError code: %d\n" - "\tError Message: %s", - error.error_code(), error.error_message().c_str()); - } else { - gpr_log( - GPR_INFO, - "Error on GetServices() response type\n\tExpecting: %d\n\tReceived: %d", - ServerReflectionResponse::MessageResponseCase::kListServicesResponse, - response.message_response_case()); - } - return false; -} - -const protobuf::FileDescriptorProto -ProtoReflectionDescriptorDatabase::ParseFileDescriptorProtoResponse( + gpr_log(GPR_INFO, + "Error on GetServices()\n\tError code: %d\n" + "\tError Message: %s", + error.error_code(), error.error_message().c_str()); + } else { + gpr_log( + GPR_INFO, + "Error on GetServices() response type\n\tExpecting: %d\n\tReceived: %d", + ServerReflectionResponse::MessageResponseCase::kListServicesResponse, + response.message_response_case()); + } + return false; +} + +const protobuf::FileDescriptorProto +ProtoReflectionDescriptorDatabase::ParseFileDescriptorProtoResponse( const TString& byte_fd_proto) { - protobuf::FileDescriptorProto file_desc_proto; - file_desc_proto.ParseFromString(google::protobuf::string(byte_fd_proto)); - return file_desc_proto; -} - -void ProtoReflectionDescriptorDatabase::AddFileFromResponse( - const grpc::reflection::v1alpha::FileDescriptorResponse& response) { - for (int i = 0; i < response.file_descriptor_proto_size(); ++i) { - const protobuf::FileDescriptorProto file_proto = - ParseFileDescriptorProtoResponse(response.file_descriptor_proto(i)); - if (known_files_.find(file_proto.name()) == known_files_.end()) { - known_files_.insert(file_proto.name()); - cached_db_.Add(file_proto); - } - } -} - -const std::shared_ptr<ProtoReflectionDescriptorDatabase::ClientStream> -ProtoReflectionDescriptorDatabase::GetStream() { - if (!stream_) { - stream_ = stub_->ServerReflectionInfo(&ctx_); - } - return stream_; -} - -bool ProtoReflectionDescriptorDatabase::DoOneRequest( - const ServerReflectionRequest& request, - ServerReflectionResponse& response) { - bool success = false; - stream_mutex_.lock(); - if (GetStream()->Write(request) && GetStream()->Read(&response)) { - success = true; - } - stream_mutex_.unlock(); - return success; -} - -} // namespace grpc + protobuf::FileDescriptorProto file_desc_proto; + file_desc_proto.ParseFromString(google::protobuf::string(byte_fd_proto)); + return file_desc_proto; +} + +void ProtoReflectionDescriptorDatabase::AddFileFromResponse( + const grpc::reflection::v1alpha::FileDescriptorResponse& response) { + for (int i = 0; i < response.file_descriptor_proto_size(); ++i) { + const protobuf::FileDescriptorProto file_proto = + ParseFileDescriptorProtoResponse(response.file_descriptor_proto(i)); + if (known_files_.find(file_proto.name()) == known_files_.end()) { + known_files_.insert(file_proto.name()); + cached_db_.Add(file_proto); + } + } +} + +const std::shared_ptr<ProtoReflectionDescriptorDatabase::ClientStream> +ProtoReflectionDescriptorDatabase::GetStream() { + if (!stream_) { + stream_ = stub_->ServerReflectionInfo(&ctx_); + } + return stream_; +} + +bool ProtoReflectionDescriptorDatabase::DoOneRequest( + const ServerReflectionRequest& request, + ServerReflectionResponse& response) { + bool success = false; + stream_mutex_.lock(); + if (GetStream()->Write(request) && GetStream()->Read(&response)) { + success = true; + } + stream_mutex_.unlock(); + return success; +} + +} // namespace grpc diff --git a/contrib/libs/grpc/test/cpp/util/proto_reflection_descriptor_database.h b/contrib/libs/grpc/test/cpp/util/proto_reflection_descriptor_database.h index cdd6f0cccde..1c849a6f8a4 100644 --- a/contrib/libs/grpc/test/cpp/util/proto_reflection_descriptor_database.h +++ b/contrib/libs/grpc/test/cpp/util/proto_reflection_descriptor_database.h @@ -1,111 +1,111 @@ -/* - * - * Copyright 2016 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. - * - */ -#ifndef GRPC_TEST_CPP_PROTO_SERVER_REFLECTION_DATABSE_H -#define GRPC_TEST_CPP_PROTO_SERVER_REFLECTION_DATABSE_H - -#include <mutex> -#include <unordered_map> -#include <unordered_set> -#include <vector> - -#include <grpcpp/grpcpp.h> -#include <grpcpp/impl/codegen/config_protobuf.h> -#include "src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h" - -namespace grpc { - -// ProtoReflectionDescriptorDatabase takes a stub of ServerReflection and -// provides the methods defined by DescriptorDatabase interfaces. It can be used -// to feed a DescriptorPool instance. -class ProtoReflectionDescriptorDatabase : public protobuf::DescriptorDatabase { - public: - explicit ProtoReflectionDescriptorDatabase( - std::unique_ptr<reflection::v1alpha::ServerReflection::Stub> stub); - - explicit ProtoReflectionDescriptorDatabase( +/* + * + * Copyright 2016 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. + * + */ +#ifndef GRPC_TEST_CPP_PROTO_SERVER_REFLECTION_DATABSE_H +#define GRPC_TEST_CPP_PROTO_SERVER_REFLECTION_DATABSE_H + +#include <mutex> +#include <unordered_map> +#include <unordered_set> +#include <vector> + +#include <grpcpp/grpcpp.h> +#include <grpcpp/impl/codegen/config_protobuf.h> +#include "src/proto/grpc/reflection/v1alpha/reflection.grpc.pb.h" + +namespace grpc { + +// ProtoReflectionDescriptorDatabase takes a stub of ServerReflection and +// provides the methods defined by DescriptorDatabase interfaces. It can be used +// to feed a DescriptorPool instance. +class ProtoReflectionDescriptorDatabase : public protobuf::DescriptorDatabase { + public: + explicit ProtoReflectionDescriptorDatabase( + std::unique_ptr<reflection::v1alpha::ServerReflection::Stub> stub); + + explicit ProtoReflectionDescriptorDatabase( const std::shared_ptr<grpc::Channel>& channel); - - virtual ~ProtoReflectionDescriptorDatabase(); - - // The following four methods implement DescriptorDatabase interfaces. - // + + virtual ~ProtoReflectionDescriptorDatabase(); + + // The following four methods implement DescriptorDatabase interfaces. + // // Find a file by file name. Fills in *output and returns true if found. - // Otherwise, returns false, leaving the contents of *output undefined. - bool FindFileByName(const google::protobuf::string& filename, - protobuf::FileDescriptorProto* output) override; - - // Find the file that declares the given fully-qualified symbol name. - // If found, fills in *output and returns true, otherwise returns false - // and leaves *output undefined. - bool FindFileContainingSymbol(const google::protobuf::string& symbol_name, - protobuf::FileDescriptorProto* output) override; - - // Find the file which defines an extension extending the given message type - // with the given field number. If found, fills in *output and returns true, - // otherwise returns false and leaves *output undefined. containing_type - // must be a fully-qualified type name. - bool FindFileContainingExtension( - const google::protobuf::string& containing_type, int field_number, - protobuf::FileDescriptorProto* output) override; - - // Finds the tag numbers used by all known extensions of - // extendee_type, and appends them to output in an undefined - // order. This method is best-effort: it's not guaranteed that the - // database will find all extensions, and it's not guaranteed that - // FindFileContainingExtension will return true on all of the found - // numbers. Returns true if the search was successful, otherwise - // returns false and leaves output unchanged. - bool FindAllExtensionNumbers(const google::protobuf::string& extendee_type, - std::vector<int>* output) override; - - // Provide a list of full names of registered services + // Otherwise, returns false, leaving the contents of *output undefined. + bool FindFileByName(const google::protobuf::string& filename, + protobuf::FileDescriptorProto* output) override; + + // Find the file that declares the given fully-qualified symbol name. + // If found, fills in *output and returns true, otherwise returns false + // and leaves *output undefined. + bool FindFileContainingSymbol(const google::protobuf::string& symbol_name, + protobuf::FileDescriptorProto* output) override; + + // Find the file which defines an extension extending the given message type + // with the given field number. If found, fills in *output and returns true, + // otherwise returns false and leaves *output undefined. containing_type + // must be a fully-qualified type name. + bool FindFileContainingExtension( + const google::protobuf::string& containing_type, int field_number, + protobuf::FileDescriptorProto* output) override; + + // Finds the tag numbers used by all known extensions of + // extendee_type, and appends them to output in an undefined + // order. This method is best-effort: it's not guaranteed that the + // database will find all extensions, and it's not guaranteed that + // FindFileContainingExtension will return true on all of the found + // numbers. Returns true if the search was successful, otherwise + // returns false and leaves output unchanged. + bool FindAllExtensionNumbers(const google::protobuf::string& extendee_type, + std::vector<int>* output) override; + + // Provide a list of full names of registered services bool GetServices(std::vector<TString>* output); - - private: - typedef ClientReaderWriter< - grpc::reflection::v1alpha::ServerReflectionRequest, - grpc::reflection::v1alpha::ServerReflectionResponse> - ClientStream; - - const protobuf::FileDescriptorProto ParseFileDescriptorProtoResponse( + + private: + typedef ClientReaderWriter< + grpc::reflection::v1alpha::ServerReflectionRequest, + grpc::reflection::v1alpha::ServerReflectionResponse> + ClientStream; + + const protobuf::FileDescriptorProto ParseFileDescriptorProtoResponse( const TString& byte_fd_proto); - - void AddFileFromResponse( - const grpc::reflection::v1alpha::FileDescriptorResponse& response); - - const std::shared_ptr<ClientStream> GetStream(); - - bool DoOneRequest( - const grpc::reflection::v1alpha::ServerReflectionRequest& request, - grpc::reflection::v1alpha::ServerReflectionResponse& response); - - std::shared_ptr<ClientStream> stream_; - grpc::ClientContext ctx_; - std::unique_ptr<grpc::reflection::v1alpha::ServerReflection::Stub> stub_; - std::unordered_set<string> known_files_; - std::unordered_set<string> missing_symbols_; - std::unordered_map<string, std::unordered_set<int>> missing_extensions_; - std::unordered_map<string, std::vector<int>> cached_extension_numbers_; - std::mutex stream_mutex_; - - protobuf::SimpleDescriptorDatabase cached_db_; -}; - -} // namespace grpc - -#endif // GRPC_TEST_CPP_METRICS_SERVER_H + + void AddFileFromResponse( + const grpc::reflection::v1alpha::FileDescriptorResponse& response); + + const std::shared_ptr<ClientStream> GetStream(); + + bool DoOneRequest( + const grpc::reflection::v1alpha::ServerReflectionRequest& request, + grpc::reflection::v1alpha::ServerReflectionResponse& response); + + std::shared_ptr<ClientStream> stream_; + grpc::ClientContext ctx_; + std::unique_ptr<grpc::reflection::v1alpha::ServerReflection::Stub> stub_; + std::unordered_set<string> known_files_; + std::unordered_set<string> missing_symbols_; + std::unordered_map<string, std::unordered_set<int>> missing_extensions_; + std::unordered_map<string, std::vector<int>> cached_extension_numbers_; + std::mutex stream_mutex_; + + protobuf::SimpleDescriptorDatabase cached_db_; +}; + +} // namespace grpc + +#endif // GRPC_TEST_CPP_METRICS_SERVER_H diff --git a/contrib/libs/grpc/test/cpp/util/service_describer.cc b/contrib/libs/grpc/test/cpp/util/service_describer.cc index 2af1104b979..8fb0c965c54 100644 --- a/contrib/libs/grpc/test/cpp/util/service_describer.cc +++ b/contrib/libs/grpc/test/cpp/util/service_describer.cc @@ -1,92 +1,92 @@ -/* - * - * Copyright 2016 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 "test/cpp/util/service_describer.h" - -#include <iostream> -#include <sstream> +/* + * + * Copyright 2016 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 "test/cpp/util/service_describer.h" + +#include <iostream> +#include <sstream> #include <util/generic/string.h> -#include <vector> - -namespace grpc { -namespace testing { - +#include <vector> + +namespace grpc { +namespace testing { + TString DescribeServiceList(std::vector<TString> service_list, grpc::protobuf::DescriptorPool& desc_pool) { - std::stringstream result; - for (auto it = service_list.begin(); it != service_list.end(); it++) { - auto const& service = *it; - const grpc::protobuf::ServiceDescriptor* service_desc = - desc_pool.FindServiceByName(google::protobuf::string(service)); - if (service_desc != nullptr) { - result << DescribeService(service_desc); - } - } - return result.str(); -} - + std::stringstream result; + for (auto it = service_list.begin(); it != service_list.end(); it++) { + auto const& service = *it; + const grpc::protobuf::ServiceDescriptor* service_desc = + desc_pool.FindServiceByName(google::protobuf::string(service)); + if (service_desc != nullptr) { + result << DescribeService(service_desc); + } + } + return result.str(); +} + TString DescribeService(const grpc::protobuf::ServiceDescriptor* service) { TString result; - if (service->options().deprecated()) { - result.append("DEPRECATED\n"); - } - result.append("filename: " + service->file()->name() + "\n"); - + if (service->options().deprecated()) { + result.append("DEPRECATED\n"); + } + result.append("filename: " + service->file()->name() + "\n"); + TString package = service->full_name(); - size_t pos = package.rfind("." + service->name()); + size_t pos = package.rfind("." + service->name()); if (pos != TString::npos) { - package.erase(pos); - result.append("package: " + package + ";\n"); - } - result.append("service " + service->name() + " {\n"); - for (int i = 0; i < service->method_count(); ++i) { - result.append(DescribeMethod(service->method(i))); - } - result.append("}\n\n"); - return result; -} - + package.erase(pos); + result.append("package: " + package + ";\n"); + } + result.append("service " + service->name() + " {\n"); + for (int i = 0; i < service->method_count(); ++i) { + result.append(DescribeMethod(service->method(i))); + } + result.append("}\n\n"); + return result; +} + TString DescribeMethod(const grpc::protobuf::MethodDescriptor* method) { - std::stringstream result; - result << " rpc " << method->name() - << (method->client_streaming() ? "(stream " : "(") - << method->input_type()->full_name() << ") returns " - << (method->server_streaming() ? "(stream " : "(") - << method->output_type()->full_name() << ") {}\n"; - if (method->options().deprecated()) { - result << " DEPRECATED"; - } - return result.str(); -} - + std::stringstream result; + result << " rpc " << method->name() + << (method->client_streaming() ? "(stream " : "(") + << method->input_type()->full_name() << ") returns " + << (method->server_streaming() ? "(stream " : "(") + << method->output_type()->full_name() << ") {}\n"; + if (method->options().deprecated()) { + result << " DEPRECATED"; + } + return result.str(); +} + TString SummarizeService(const grpc::protobuf::ServiceDescriptor* service) { TString result; - for (int i = 0; i < service->method_count(); ++i) { - result.append(SummarizeMethod(service->method(i))); - } - return result; -} - + for (int i = 0; i < service->method_count(); ++i) { + result.append(SummarizeMethod(service->method(i))); + } + return result; +} + TString SummarizeMethod(const grpc::protobuf::MethodDescriptor* method) { TString result = method->name(); - result.append("\n"); - return result; -} - -} // namespace testing -} // namespace grpc + result.append("\n"); + return result; +} + +} // namespace testing +} // namespace grpc diff --git a/contrib/libs/grpc/test/cpp/util/service_describer.h b/contrib/libs/grpc/test/cpp/util/service_describer.h index a473f03744a..d71f477d093 100644 --- a/contrib/libs/grpc/test/cpp/util/service_describer.h +++ b/contrib/libs/grpc/test/cpp/util/service_describer.h @@ -1,42 +1,42 @@ -/* - * - * Copyright 2016 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. - * - */ - -#ifndef GRPC_TEST_CPP_UTIL_SERVICE_DESCRIBER_H -#define GRPC_TEST_CPP_UTIL_SERVICE_DESCRIBER_H - -#include <grpcpp/support/config.h> -#include "test/cpp/util/config_grpc_cli.h" - -namespace grpc { -namespace testing { - +/* + * + * Copyright 2016 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. + * + */ + +#ifndef GRPC_TEST_CPP_UTIL_SERVICE_DESCRIBER_H +#define GRPC_TEST_CPP_UTIL_SERVICE_DESCRIBER_H + +#include <grpcpp/support/config.h> +#include "test/cpp/util/config_grpc_cli.h" + +namespace grpc { +namespace testing { + TString DescribeServiceList(std::vector<TString> service_list, grpc::protobuf::DescriptorPool& desc_pool); - + TString DescribeService(const grpc::protobuf::ServiceDescriptor* service); - + TString DescribeMethod(const grpc::protobuf::MethodDescriptor* method); - + TString SummarizeService(const grpc::protobuf::ServiceDescriptor* service); - + TString SummarizeMethod(const grpc::protobuf::MethodDescriptor* method); - -} // namespace testing -} // namespace grpc - -#endif // GRPC_TEST_CPP_UTIL_SERVICE_DESCRIBER_H + +} // namespace testing +} // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_SERVICE_DESCRIBER_H diff --git a/contrib/libs/grpc/test/cpp/util/slice_test.cc b/contrib/libs/grpc/test/cpp/util/slice_test.cc index d7e945ae383..fea5e9e19b0 100644 --- a/contrib/libs/grpc/test/cpp/util/slice_test.cc +++ b/contrib/libs/grpc/test/cpp/util/slice_test.cc @@ -1,144 +1,144 @@ -/* - * - * 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. - * - */ - -#include <grpc++/support/slice.h> -#include <grpcpp/impl/grpc_library.h> - -#include <grpc/grpc.h> -#include <grpc/slice.h> -#include <gtest/gtest.h> - +/* + * + * 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. + * + */ + +#include <grpc++/support/slice.h> +#include <grpcpp/impl/grpc_library.h> + +#include <grpc/grpc.h> +#include <grpc/slice.h> +#include <gtest/gtest.h> + #include "test/core/util/test_config.h" -namespace grpc { - -static internal::GrpcLibraryInitializer g_gli_initializer; - -namespace { - -const char* kContent = "hello xxxxxxxxxxxxxxxxxxxx world"; - -class SliceTest : public ::testing::Test { - protected: +namespace grpc { + +static internal::GrpcLibraryInitializer g_gli_initializer; + +namespace { + +const char* kContent = "hello xxxxxxxxxxxxxxxxxxxx world"; + +class SliceTest : public ::testing::Test { + protected: static void SetUpTestCase() { grpc_init(); } static void TearDownTestCase() { grpc_shutdown(); } void CheckSliceSize(const Slice& s, const TString& content) { - EXPECT_EQ(content.size(), s.size()); - } + EXPECT_EQ(content.size(), s.size()); + } void CheckSlice(const Slice& s, const TString& content) { - EXPECT_EQ(content.size(), s.size()); - EXPECT_EQ(content, + EXPECT_EQ(content.size(), s.size()); + EXPECT_EQ(content, TString(reinterpret_cast<const char*>(s.begin()), s.size())); - } -}; - -TEST_F(SliceTest, Empty) { - Slice empty_slice; - CheckSlice(empty_slice, ""); -} - -TEST_F(SliceTest, Sized) { - Slice sized_slice(strlen(kContent)); - CheckSliceSize(sized_slice, kContent); -} - -TEST_F(SliceTest, String) { - Slice spp(kContent); - CheckSlice(spp, kContent); -} - -TEST_F(SliceTest, Buf) { - Slice spp(kContent, strlen(kContent)); - CheckSlice(spp, kContent); -} - -TEST_F(SliceTest, StaticBuf) { - Slice spp(kContent, strlen(kContent), Slice::STATIC_SLICE); - CheckSlice(spp, kContent); -} - -TEST_F(SliceTest, SliceNew) { - char* x = new char[strlen(kContent) + 1]; - strcpy(x, kContent); - Slice spp(x, strlen(x), [](void* p) { delete[] static_cast<char*>(p); }); - CheckSlice(spp, kContent); -} - -TEST_F(SliceTest, SliceNewDoNothing) { + } +}; + +TEST_F(SliceTest, Empty) { + Slice empty_slice; + CheckSlice(empty_slice, ""); +} + +TEST_F(SliceTest, Sized) { + Slice sized_slice(strlen(kContent)); + CheckSliceSize(sized_slice, kContent); +} + +TEST_F(SliceTest, String) { + Slice spp(kContent); + CheckSlice(spp, kContent); +} + +TEST_F(SliceTest, Buf) { + Slice spp(kContent, strlen(kContent)); + CheckSlice(spp, kContent); +} + +TEST_F(SliceTest, StaticBuf) { + Slice spp(kContent, strlen(kContent), Slice::STATIC_SLICE); + CheckSlice(spp, kContent); +} + +TEST_F(SliceTest, SliceNew) { + char* x = new char[strlen(kContent) + 1]; + strcpy(x, kContent); + Slice spp(x, strlen(x), [](void* p) { delete[] static_cast<char*>(p); }); + CheckSlice(spp, kContent); +} + +TEST_F(SliceTest, SliceNewDoNothing) { Slice spp(const_cast<char*>(kContent), strlen(kContent), [](void* /*p*/) {}); - CheckSlice(spp, kContent); -} - -TEST_F(SliceTest, SliceNewWithUserData) { - struct stest { - char* x; - int y; - }; - auto* t = new stest; - t->x = new char[strlen(kContent) + 1]; - strcpy(t->x, kContent); - Slice spp(t->x, strlen(t->x), - [](void* p) { - auto* t = static_cast<stest*>(p); - delete[] t->x; - delete t; - }, - t); - CheckSlice(spp, kContent); -} - -TEST_F(SliceTest, SliceNewLen) { - Slice spp(const_cast<char*>(kContent), strlen(kContent), + CheckSlice(spp, kContent); +} + +TEST_F(SliceTest, SliceNewWithUserData) { + struct stest { + char* x; + int y; + }; + auto* t = new stest; + t->x = new char[strlen(kContent) + 1]; + strcpy(t->x, kContent); + Slice spp(t->x, strlen(t->x), + [](void* p) { + auto* t = static_cast<stest*>(p); + delete[] t->x; + delete t; + }, + t); + CheckSlice(spp, kContent); +} + +TEST_F(SliceTest, SliceNewLen) { + Slice spp(const_cast<char*>(kContent), strlen(kContent), [](void* /*p*/, size_t l) { EXPECT_EQ(l, strlen(kContent)); }); - CheckSlice(spp, kContent); -} - -TEST_F(SliceTest, Steal) { - grpc_slice s = grpc_slice_from_copied_string(kContent); - Slice spp(s, Slice::STEAL_REF); - CheckSlice(spp, kContent); -} - -TEST_F(SliceTest, Add) { - grpc_slice s = grpc_slice_from_copied_string(kContent); - Slice spp(s, Slice::ADD_REF); - grpc_slice_unref(s); - CheckSlice(spp, kContent); -} - -TEST_F(SliceTest, Cslice) { - grpc_slice s = grpc_slice_from_copied_string(kContent); - Slice spp(s, Slice::STEAL_REF); - CheckSlice(spp, kContent); - grpc_slice c_slice = spp.c_slice(); - EXPECT_EQ(GRPC_SLICE_START_PTR(s), GRPC_SLICE_START_PTR(c_slice)); - EXPECT_EQ(GRPC_SLICE_END_PTR(s), GRPC_SLICE_END_PTR(c_slice)); - grpc_slice_unref(c_slice); -} - -} // namespace -} // namespace grpc - -int main(int argc, char** argv) { + CheckSlice(spp, kContent); +} + +TEST_F(SliceTest, Steal) { + grpc_slice s = grpc_slice_from_copied_string(kContent); + Slice spp(s, Slice::STEAL_REF); + CheckSlice(spp, kContent); +} + +TEST_F(SliceTest, Add) { + grpc_slice s = grpc_slice_from_copied_string(kContent); + Slice spp(s, Slice::ADD_REF); + grpc_slice_unref(s); + CheckSlice(spp, kContent); +} + +TEST_F(SliceTest, Cslice) { + grpc_slice s = grpc_slice_from_copied_string(kContent); + Slice spp(s, Slice::STEAL_REF); + CheckSlice(spp, kContent); + grpc_slice c_slice = spp.c_slice(); + EXPECT_EQ(GRPC_SLICE_START_PTR(s), GRPC_SLICE_START_PTR(c_slice)); + EXPECT_EQ(GRPC_SLICE_END_PTR(s), GRPC_SLICE_END_PTR(c_slice)); + grpc_slice_unref(c_slice); +} + +} // namespace +} // namespace grpc + +int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - int ret = RUN_ALL_TESTS(); - return ret; -} + ::testing::InitGoogleTest(&argc, argv); + int ret = RUN_ALL_TESTS(); + return ret; +} diff --git a/contrib/libs/grpc/test/cpp/util/string_ref_helper.cc b/contrib/libs/grpc/test/cpp/util/string_ref_helper.cc index e573f5d33ad..5d20347c756 100644 --- a/contrib/libs/grpc/test/cpp/util/string_ref_helper.cc +++ b/contrib/libs/grpc/test/cpp/util/string_ref_helper.cc @@ -1,29 +1,29 @@ -/* - * - * 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. - * - */ - -#include "test/cpp/util/string_ref_helper.h" - -namespace grpc { -namespace testing { - +/* + * + * 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. + * + */ + +#include "test/cpp/util/string_ref_helper.h" + +namespace grpc { +namespace testing { + TString ToString(const grpc::string_ref& r) { return TString(r.data(), r.size()); -} - -} // namespace testing -} // namespace grpc +} + +} // namespace testing +} // namespace grpc diff --git a/contrib/libs/grpc/test/cpp/util/string_ref_helper.h b/contrib/libs/grpc/test/cpp/util/string_ref_helper.h index e9e941f3192..7ea72263121 100644 --- a/contrib/libs/grpc/test/cpp/util/string_ref_helper.h +++ b/contrib/libs/grpc/test/cpp/util/string_ref_helper.h @@ -1,32 +1,32 @@ -/* - * - * 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. - * - */ - -#ifndef GRPC_TEST_CPP_UTIL_STRING_REF_HELPER_H -#define GRPC_TEST_CPP_UTIL_STRING_REF_HELPER_H - -#include <grpcpp/support/string_ref.h> - -namespace grpc { -namespace testing { - +/* + * + * 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. + * + */ + +#ifndef GRPC_TEST_CPP_UTIL_STRING_REF_HELPER_H +#define GRPC_TEST_CPP_UTIL_STRING_REF_HELPER_H + +#include <grpcpp/support/string_ref.h> + +namespace grpc { +namespace testing { + TString ToString(const grpc::string_ref& r); - -} // namespace testing -} // namespace grpc - -#endif // GRPC_TEST_CPP_UTIL_STRING_REF_HELPER_H + +} // namespace testing +} // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_STRING_REF_HELPER_H diff --git a/contrib/libs/grpc/test/cpp/util/string_ref_test.cc b/contrib/libs/grpc/test/cpp/util/string_ref_test.cc index 8e3259b764b..18c40576e11 100644 --- a/contrib/libs/grpc/test/cpp/util/string_ref_test.cc +++ b/contrib/libs/grpc/test/cpp/util/string_ref_test.cc @@ -1,205 +1,205 @@ -/* - * - * 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. - * - */ - -#include <grpcpp/support/string_ref.h> - -#include <string.h> - -#include <gtest/gtest.h> - +/* + * + * 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. + * + */ + +#include <grpcpp/support/string_ref.h> + +#include <string.h> + +#include <gtest/gtest.h> + #include "test/core/util/test_config.h" -namespace grpc { -namespace { - -const char kTestString[] = "blah"; -const char kTestStringWithEmbeddedNull[] = "blah\0foo"; -const size_t kTestStringWithEmbeddedNullLength = 8; -const char kTestUnrelatedString[] = "foo"; - -class StringRefTest : public ::testing::Test {}; - -TEST_F(StringRefTest, Empty) { - string_ref s; - EXPECT_EQ(0U, s.length()); - EXPECT_EQ(nullptr, s.data()); -} - -TEST_F(StringRefTest, FromCString) { - string_ref s(kTestString); - EXPECT_EQ(strlen(kTestString), s.length()); - EXPECT_EQ(kTestString, s.data()); -} - -TEST_F(StringRefTest, FromCStringWithLength) { - string_ref s(kTestString, 2); - EXPECT_EQ(2U, s.length()); - EXPECT_EQ(kTestString, s.data()); -} - -TEST_F(StringRefTest, FromString) { - string copy(kTestString); - string_ref s(copy); - EXPECT_EQ(copy.data(), s.data()); - EXPECT_EQ(copy.length(), s.length()); -} - -TEST_F(StringRefTest, CopyConstructor) { - string_ref s1(kTestString); - ; +namespace grpc { +namespace { + +const char kTestString[] = "blah"; +const char kTestStringWithEmbeddedNull[] = "blah\0foo"; +const size_t kTestStringWithEmbeddedNullLength = 8; +const char kTestUnrelatedString[] = "foo"; + +class StringRefTest : public ::testing::Test {}; + +TEST_F(StringRefTest, Empty) { + string_ref s; + EXPECT_EQ(0U, s.length()); + EXPECT_EQ(nullptr, s.data()); +} + +TEST_F(StringRefTest, FromCString) { + string_ref s(kTestString); + EXPECT_EQ(strlen(kTestString), s.length()); + EXPECT_EQ(kTestString, s.data()); +} + +TEST_F(StringRefTest, FromCStringWithLength) { + string_ref s(kTestString, 2); + EXPECT_EQ(2U, s.length()); + EXPECT_EQ(kTestString, s.data()); +} + +TEST_F(StringRefTest, FromString) { + string copy(kTestString); + string_ref s(copy); + EXPECT_EQ(copy.data(), s.data()); + EXPECT_EQ(copy.length(), s.length()); +} + +TEST_F(StringRefTest, CopyConstructor) { + string_ref s1(kTestString); + ; const string_ref& s2(s1); - EXPECT_EQ(s1.length(), s2.length()); - EXPECT_EQ(s1.data(), s2.data()); -} - -TEST_F(StringRefTest, FromStringWithEmbeddedNull) { - string copy(kTestStringWithEmbeddedNull, kTestStringWithEmbeddedNullLength); - string_ref s(copy); - EXPECT_EQ(copy.data(), s.data()); - EXPECT_EQ(copy.length(), s.length()); - EXPECT_EQ(kTestStringWithEmbeddedNullLength, s.length()); -} - -TEST_F(StringRefTest, Assignment) { - string_ref s1(kTestString); - ; - string_ref s2; - EXPECT_EQ(nullptr, s2.data()); - s2 = s1; - EXPECT_EQ(s1.length(), s2.length()); - EXPECT_EQ(s1.data(), s2.data()); -} - -TEST_F(StringRefTest, Iterator) { - string_ref s(kTestString); - size_t i = 0; - for (auto it = s.cbegin(); it != s.cend(); ++it) { - auto val = kTestString[i++]; - EXPECT_EQ(val, *it); - } - EXPECT_EQ(strlen(kTestString), i); -} - -TEST_F(StringRefTest, ReverseIterator) { - string_ref s(kTestString); - size_t i = strlen(kTestString); - for (auto rit = s.crbegin(); rit != s.crend(); ++rit) { - auto val = kTestString[--i]; - EXPECT_EQ(val, *rit); - } - EXPECT_EQ(0U, i); -} - -TEST_F(StringRefTest, Capacity) { - string_ref empty; - EXPECT_EQ(0U, empty.length()); - EXPECT_EQ(0U, empty.size()); - EXPECT_EQ(0U, empty.max_size()); - EXPECT_TRUE(empty.empty()); - - string_ref s(kTestString); - EXPECT_EQ(strlen(kTestString), s.length()); - EXPECT_EQ(s.length(), s.size()); - EXPECT_EQ(s.max_size(), s.length()); - EXPECT_FALSE(s.empty()); -} - -TEST_F(StringRefTest, Compare) { - string_ref s1(kTestString); - string s1_copy(kTestString); - string_ref s2(kTestUnrelatedString); - string_ref s3(kTestStringWithEmbeddedNull, kTestStringWithEmbeddedNullLength); - EXPECT_EQ(0, s1.compare(s1_copy)); - EXPECT_NE(0, s1.compare(s2)); - EXPECT_NE(0, s1.compare(s3)); -} - -TEST_F(StringRefTest, StartsWith) { - string_ref s1(kTestString); - string_ref s2(kTestUnrelatedString); - string_ref s3(kTestStringWithEmbeddedNull, kTestStringWithEmbeddedNullLength); - EXPECT_TRUE(s1.starts_with(s1)); - EXPECT_FALSE(s1.starts_with(s2)); - EXPECT_FALSE(s2.starts_with(s1)); - EXPECT_FALSE(s1.starts_with(s3)); - EXPECT_TRUE(s3.starts_with(s1)); -} - -TEST_F(StringRefTest, Endswith) { - string_ref s1(kTestString); - string_ref s2(kTestUnrelatedString); - string_ref s3(kTestStringWithEmbeddedNull, kTestStringWithEmbeddedNullLength); - EXPECT_TRUE(s1.ends_with(s1)); - EXPECT_FALSE(s1.ends_with(s2)); - EXPECT_FALSE(s2.ends_with(s1)); - EXPECT_FALSE(s2.ends_with(s3)); - EXPECT_TRUE(s3.ends_with(s2)); -} - -TEST_F(StringRefTest, Find) { - string_ref s1(kTestString); - string_ref s2(kTestUnrelatedString); - string_ref s3(kTestStringWithEmbeddedNull, kTestStringWithEmbeddedNullLength); - EXPECT_EQ(0U, s1.find(s1)); - EXPECT_EQ(0U, s2.find(s2)); - EXPECT_EQ(0U, s3.find(s3)); - EXPECT_EQ(string_ref::npos, s1.find(s2)); - EXPECT_EQ(string_ref::npos, s2.find(s1)); - EXPECT_EQ(string_ref::npos, s1.find(s3)); - EXPECT_EQ(0U, s3.find(s1)); - EXPECT_EQ(5U, s3.find(s2)); - EXPECT_EQ(string_ref::npos, s1.find('z')); - EXPECT_EQ(1U, s2.find('o')); -} - -TEST_F(StringRefTest, SubString) { - string_ref s(kTestStringWithEmbeddedNull, kTestStringWithEmbeddedNullLength); - string_ref sub1 = s.substr(0, 4); - EXPECT_EQ(string_ref(kTestString), sub1); - string_ref sub2 = s.substr(5); - EXPECT_EQ(string_ref(kTestUnrelatedString), sub2); -} - -TEST_F(StringRefTest, ComparisonOperators) { - string_ref s1(kTestString); - string_ref s2(kTestUnrelatedString); - string_ref s3(kTestStringWithEmbeddedNull, kTestStringWithEmbeddedNullLength); - EXPECT_EQ(s1, s1); - EXPECT_EQ(s2, s2); - EXPECT_EQ(s3, s3); - EXPECT_GE(s1, s1); - EXPECT_GE(s2, s2); - EXPECT_GE(s3, s3); - EXPECT_LE(s1, s1); - EXPECT_LE(s2, s2); - EXPECT_LE(s3, s3); - EXPECT_NE(s1, s2); - EXPECT_NE(s1, s3); - EXPECT_NE(s2, s3); - EXPECT_GT(s3, s1); - EXPECT_LT(s1, s3); -} - -} // namespace -} // namespace grpc - -int main(int argc, char** argv) { + EXPECT_EQ(s1.length(), s2.length()); + EXPECT_EQ(s1.data(), s2.data()); +} + +TEST_F(StringRefTest, FromStringWithEmbeddedNull) { + string copy(kTestStringWithEmbeddedNull, kTestStringWithEmbeddedNullLength); + string_ref s(copy); + EXPECT_EQ(copy.data(), s.data()); + EXPECT_EQ(copy.length(), s.length()); + EXPECT_EQ(kTestStringWithEmbeddedNullLength, s.length()); +} + +TEST_F(StringRefTest, Assignment) { + string_ref s1(kTestString); + ; + string_ref s2; + EXPECT_EQ(nullptr, s2.data()); + s2 = s1; + EXPECT_EQ(s1.length(), s2.length()); + EXPECT_EQ(s1.data(), s2.data()); +} + +TEST_F(StringRefTest, Iterator) { + string_ref s(kTestString); + size_t i = 0; + for (auto it = s.cbegin(); it != s.cend(); ++it) { + auto val = kTestString[i++]; + EXPECT_EQ(val, *it); + } + EXPECT_EQ(strlen(kTestString), i); +} + +TEST_F(StringRefTest, ReverseIterator) { + string_ref s(kTestString); + size_t i = strlen(kTestString); + for (auto rit = s.crbegin(); rit != s.crend(); ++rit) { + auto val = kTestString[--i]; + EXPECT_EQ(val, *rit); + } + EXPECT_EQ(0U, i); +} + +TEST_F(StringRefTest, Capacity) { + string_ref empty; + EXPECT_EQ(0U, empty.length()); + EXPECT_EQ(0U, empty.size()); + EXPECT_EQ(0U, empty.max_size()); + EXPECT_TRUE(empty.empty()); + + string_ref s(kTestString); + EXPECT_EQ(strlen(kTestString), s.length()); + EXPECT_EQ(s.length(), s.size()); + EXPECT_EQ(s.max_size(), s.length()); + EXPECT_FALSE(s.empty()); +} + +TEST_F(StringRefTest, Compare) { + string_ref s1(kTestString); + string s1_copy(kTestString); + string_ref s2(kTestUnrelatedString); + string_ref s3(kTestStringWithEmbeddedNull, kTestStringWithEmbeddedNullLength); + EXPECT_EQ(0, s1.compare(s1_copy)); + EXPECT_NE(0, s1.compare(s2)); + EXPECT_NE(0, s1.compare(s3)); +} + +TEST_F(StringRefTest, StartsWith) { + string_ref s1(kTestString); + string_ref s2(kTestUnrelatedString); + string_ref s3(kTestStringWithEmbeddedNull, kTestStringWithEmbeddedNullLength); + EXPECT_TRUE(s1.starts_with(s1)); + EXPECT_FALSE(s1.starts_with(s2)); + EXPECT_FALSE(s2.starts_with(s1)); + EXPECT_FALSE(s1.starts_with(s3)); + EXPECT_TRUE(s3.starts_with(s1)); +} + +TEST_F(StringRefTest, Endswith) { + string_ref s1(kTestString); + string_ref s2(kTestUnrelatedString); + string_ref s3(kTestStringWithEmbeddedNull, kTestStringWithEmbeddedNullLength); + EXPECT_TRUE(s1.ends_with(s1)); + EXPECT_FALSE(s1.ends_with(s2)); + EXPECT_FALSE(s2.ends_with(s1)); + EXPECT_FALSE(s2.ends_with(s3)); + EXPECT_TRUE(s3.ends_with(s2)); +} + +TEST_F(StringRefTest, Find) { + string_ref s1(kTestString); + string_ref s2(kTestUnrelatedString); + string_ref s3(kTestStringWithEmbeddedNull, kTestStringWithEmbeddedNullLength); + EXPECT_EQ(0U, s1.find(s1)); + EXPECT_EQ(0U, s2.find(s2)); + EXPECT_EQ(0U, s3.find(s3)); + EXPECT_EQ(string_ref::npos, s1.find(s2)); + EXPECT_EQ(string_ref::npos, s2.find(s1)); + EXPECT_EQ(string_ref::npos, s1.find(s3)); + EXPECT_EQ(0U, s3.find(s1)); + EXPECT_EQ(5U, s3.find(s2)); + EXPECT_EQ(string_ref::npos, s1.find('z')); + EXPECT_EQ(1U, s2.find('o')); +} + +TEST_F(StringRefTest, SubString) { + string_ref s(kTestStringWithEmbeddedNull, kTestStringWithEmbeddedNullLength); + string_ref sub1 = s.substr(0, 4); + EXPECT_EQ(string_ref(kTestString), sub1); + string_ref sub2 = s.substr(5); + EXPECT_EQ(string_ref(kTestUnrelatedString), sub2); +} + +TEST_F(StringRefTest, ComparisonOperators) { + string_ref s1(kTestString); + string_ref s2(kTestUnrelatedString); + string_ref s3(kTestStringWithEmbeddedNull, kTestStringWithEmbeddedNullLength); + EXPECT_EQ(s1, s1); + EXPECT_EQ(s2, s2); + EXPECT_EQ(s3, s3); + EXPECT_GE(s1, s1); + EXPECT_GE(s2, s2); + EXPECT_GE(s3, s3); + EXPECT_LE(s1, s1); + EXPECT_LE(s2, s2); + EXPECT_LE(s3, s3); + EXPECT_NE(s1, s2); + EXPECT_NE(s1, s3); + EXPECT_NE(s2, s3); + EXPECT_GT(s3, s1); + EXPECT_LT(s1, s3); +} + +} // namespace +} // namespace grpc + +int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/contrib/libs/grpc/test/cpp/util/subprocess.cc b/contrib/libs/grpc/test/cpp/util/subprocess.cc index 648bd50274b..db765e31886 100644 --- a/contrib/libs/grpc/test/cpp/util/subprocess.cc +++ b/contrib/libs/grpc/test/cpp/util/subprocess.cc @@ -1,44 +1,44 @@ -/* - * - * 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. - * - */ - -#include "test/cpp/util/subprocess.h" - -#include <vector> - -#include "test/core/util/subprocess.h" - -namespace grpc { - +/* + * + * 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. + * + */ + +#include "test/cpp/util/subprocess.h" + +#include <vector> + +#include "test/core/util/subprocess.h" + +namespace grpc { + static gpr_subprocess* MakeProcess(const std::vector<TString>& args) { - std::vector<const char*> vargs; - for (auto it = args.begin(); it != args.end(); ++it) { - vargs.push_back(it->c_str()); - } - return gpr_subprocess_create(vargs.size(), &vargs[0]); -} - + std::vector<const char*> vargs; + for (auto it = args.begin(); it != args.end(); ++it) { + vargs.push_back(it->c_str()); + } + return gpr_subprocess_create(vargs.size(), &vargs[0]); +} + SubProcess::SubProcess(const std::vector<TString>& args) - : subprocess_(MakeProcess(args)) {} - -SubProcess::~SubProcess() { gpr_subprocess_destroy(subprocess_); } - -int SubProcess::Join() { return gpr_subprocess_join(subprocess_); } - -void SubProcess::Interrupt() { gpr_subprocess_interrupt(subprocess_); } - -} // namespace grpc + : subprocess_(MakeProcess(args)) {} + +SubProcess::~SubProcess() { gpr_subprocess_destroy(subprocess_); } + +int SubProcess::Join() { return gpr_subprocess_join(subprocess_); } + +void SubProcess::Interrupt() { gpr_subprocess_interrupt(subprocess_); } + +} // namespace grpc diff --git a/contrib/libs/grpc/test/cpp/util/subprocess.h b/contrib/libs/grpc/test/cpp/util/subprocess.h index 84dda31dd15..9470355ff39 100644 --- a/contrib/libs/grpc/test/cpp/util/subprocess.h +++ b/contrib/libs/grpc/test/cpp/util/subprocess.h @@ -1,47 +1,47 @@ -/* - * - * 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. - * - */ - -#ifndef GRPC_TEST_CPP_UTIL_SUBPROCESS_H -#define GRPC_TEST_CPP_UTIL_SUBPROCESS_H - -#include <initializer_list> +/* + * + * 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. + * + */ + +#ifndef GRPC_TEST_CPP_UTIL_SUBPROCESS_H +#define GRPC_TEST_CPP_UTIL_SUBPROCESS_H + +#include <initializer_list> #include <util/generic/string.h> -#include <vector> - -struct gpr_subprocess; - -namespace grpc { - -class SubProcess { - public: +#include <vector> + +struct gpr_subprocess; + +namespace grpc { + +class SubProcess { + public: SubProcess(const std::vector<TString>& args); - ~SubProcess(); - - int Join(); - void Interrupt(); - - private: - SubProcess(const SubProcess& other); - SubProcess& operator=(const SubProcess& other); - - gpr_subprocess* const subprocess_; -}; - -} // namespace grpc - -#endif // GRPC_TEST_CPP_UTIL_SUBPROCESS_H + ~SubProcess(); + + int Join(); + void Interrupt(); + + private: + SubProcess(const SubProcess& other); + SubProcess& operator=(const SubProcess& other); + + gpr_subprocess* const subprocess_; +}; + +} // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_SUBPROCESS_H diff --git a/contrib/libs/grpc/test/cpp/util/test_config.h b/contrib/libs/grpc/test/cpp/util/test_config.h index 094ed44f632..e62c568d24e 100644 --- a/contrib/libs/grpc/test/cpp/util/test_config.h +++ b/contrib/libs/grpc/test/cpp/util/test_config.h @@ -1,30 +1,30 @@ -/* - * - * 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. - * - */ - -#ifndef GRPC_TEST_CPP_UTIL_TEST_CONFIG_H -#define GRPC_TEST_CPP_UTIL_TEST_CONFIG_H - -namespace grpc { -namespace testing { - -void InitTest(int* argc, char*** argv, bool remove_flags); - -} // namespace testing -} // namespace grpc - -#endif // GRPC_TEST_CPP_UTIL_TEST_CONFIG_H +/* + * + * 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. + * + */ + +#ifndef GRPC_TEST_CPP_UTIL_TEST_CONFIG_H +#define GRPC_TEST_CPP_UTIL_TEST_CONFIG_H + +namespace grpc { +namespace testing { + +void InitTest(int* argc, char*** argv, bool remove_flags); + +} // namespace testing +} // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_TEST_CONFIG_H diff --git a/contrib/libs/grpc/test/cpp/util/test_config_cc.cc b/contrib/libs/grpc/test/cpp/util/test_config_cc.cc index e4b68863354..044477a6078 100644 --- a/contrib/libs/grpc/test/cpp/util/test_config_cc.cc +++ b/contrib/libs/grpc/test/cpp/util/test_config_cc.cc @@ -1,37 +1,37 @@ -/* - * - * 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. - * - */ - -#include <gflags/gflags.h> -#include "test/cpp/util/test_config.h" - -// In some distros, gflags is in the namespace google, and in some others, -// in gflags. This hack is enabling us to find both. -namespace google {} -namespace gflags {} -using namespace google; -using namespace gflags; - -namespace grpc { -namespace testing { - -void InitTest(int* argc, char*** argv, bool remove_flags) { - ParseCommandLineFlags(argc, argv, remove_flags); -} - -} // namespace testing -} // namespace grpc +/* + * + * 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. + * + */ + +#include <gflags/gflags.h> +#include "test/cpp/util/test_config.h" + +// In some distros, gflags is in the namespace google, and in some others, +// in gflags. This hack is enabling us to find both. +namespace google {} +namespace gflags {} +using namespace google; +using namespace gflags; + +namespace grpc { +namespace testing { + +void InitTest(int* argc, char*** argv, bool remove_flags) { + ParseCommandLineFlags(argc, argv, remove_flags); +} + +} // namespace testing +} // namespace grpc diff --git a/contrib/libs/grpc/test/cpp/util/test_credentials_provider.cc b/contrib/libs/grpc/test/cpp/util/test_credentials_provider.cc index f7134b773fb..5a0e04a3485 100644 --- a/contrib/libs/grpc/test/cpp/util/test_credentials_provider.cc +++ b/contrib/libs/grpc/test/cpp/util/test_credentials_provider.cc @@ -1,45 +1,45 @@ - -/* - * - * Copyright 2016 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 "test/cpp/util/test_credentials_provider.h" - + +/* + * + * Copyright 2016 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 "test/cpp/util/test_credentials_provider.h" + #include <cstdio> #include <fstream> #include <iostream> -#include <mutex> -#include <unordered_map> - +#include <mutex> +#include <unordered_map> + #include <gflags/gflags.h> -#include <grpc/support/log.h> -#include <grpc/support/sync.h> +#include <grpc/support/log.h> +#include <grpc/support/sync.h> #include <grpcpp/security/server_credentials.h> - -#include "test/core/end2end/data/ssl_test_data.h" - + +#include "test/core/end2end/data/ssl_test_data.h" + DEFINE_string(tls_cert_file, "", "The TLS cert file used when --use_tls=true"); DEFINE_string(tls_key_file, "", "The TLS key file used when --use_tls=true"); -namespace grpc { -namespace testing { -namespace { - +namespace grpc { +namespace testing { +namespace { + TString ReadFile(const TString& src_path) { std::ifstream src; src.open(src_path, std::ifstream::in | std::ifstream::binary); @@ -53,8 +53,8 @@ TString ReadFile(const TString& src_path) { return contents; } -class DefaultCredentialsProvider : public CredentialsProvider { - public: +class DefaultCredentialsProvider : public CredentialsProvider { + public: DefaultCredentialsProvider() { if (!FLAGS_tls_key_file.empty()) { custom_server_key_ = ReadFile(FLAGS_tls_key_file); @@ -63,61 +63,61 @@ class DefaultCredentialsProvider : public CredentialsProvider { custom_server_cert_ = ReadFile(FLAGS_tls_cert_file); } } - ~DefaultCredentialsProvider() override {} - - void AddSecureType( + ~DefaultCredentialsProvider() override {} + + void AddSecureType( const TString& type, - std::unique_ptr<CredentialTypeProvider> type_provider) override { - // This clobbers any existing entry for type, except the defaults, which - // can't be clobbered. - std::unique_lock<std::mutex> lock(mu_); - auto it = std::find(added_secure_type_names_.begin(), - added_secure_type_names_.end(), type); - if (it == added_secure_type_names_.end()) { - added_secure_type_names_.push_back(type); - added_secure_type_providers_.push_back(std::move(type_provider)); - } else { - added_secure_type_providers_[it - added_secure_type_names_.begin()] = - std::move(type_provider); - } - } - - std::shared_ptr<ChannelCredentials> GetChannelCredentials( + std::unique_ptr<CredentialTypeProvider> type_provider) override { + // This clobbers any existing entry for type, except the defaults, which + // can't be clobbered. + std::unique_lock<std::mutex> lock(mu_); + auto it = std::find(added_secure_type_names_.begin(), + added_secure_type_names_.end(), type); + if (it == added_secure_type_names_.end()) { + added_secure_type_names_.push_back(type); + added_secure_type_providers_.push_back(std::move(type_provider)); + } else { + added_secure_type_providers_[it - added_secure_type_names_.begin()] = + std::move(type_provider); + } + } + + std::shared_ptr<ChannelCredentials> GetChannelCredentials( const TString& type, ChannelArguments* args) override { - if (type == grpc::testing::kInsecureCredentialsType) { - return InsecureChannelCredentials(); - } else if (type == grpc::testing::kAltsCredentialsType) { - grpc::experimental::AltsCredentialsOptions alts_opts; - return grpc::experimental::AltsCredentials(alts_opts); - } else if (type == grpc::testing::kTlsCredentialsType) { - SslCredentialsOptions ssl_opts = {test_root_cert, "", ""}; - args->SetSslTargetNameOverride("foo.test.google.fr"); + if (type == grpc::testing::kInsecureCredentialsType) { + return InsecureChannelCredentials(); + } else if (type == grpc::testing::kAltsCredentialsType) { + grpc::experimental::AltsCredentialsOptions alts_opts; + return grpc::experimental::AltsCredentials(alts_opts); + } else if (type == grpc::testing::kTlsCredentialsType) { + SslCredentialsOptions ssl_opts = {test_root_cert, "", ""}; + args->SetSslTargetNameOverride("foo.test.google.fr"); return grpc::SslCredentials(ssl_opts); } else if (type == grpc::testing::kGoogleDefaultCredentialsType) { return grpc::GoogleDefaultCredentials(); - } else { - std::unique_lock<std::mutex> lock(mu_); - auto it(std::find(added_secure_type_names_.begin(), - added_secure_type_names_.end(), type)); - if (it == added_secure_type_names_.end()) { - gpr_log(GPR_ERROR, "Unsupported credentials type %s.", type.c_str()); - return nullptr; - } - return added_secure_type_providers_[it - added_secure_type_names_.begin()] - ->GetChannelCredentials(args); - } - } - - std::shared_ptr<ServerCredentials> GetServerCredentials( + } else { + std::unique_lock<std::mutex> lock(mu_); + auto it(std::find(added_secure_type_names_.begin(), + added_secure_type_names_.end(), type)); + if (it == added_secure_type_names_.end()) { + gpr_log(GPR_ERROR, "Unsupported credentials type %s.", type.c_str()); + return nullptr; + } + return added_secure_type_providers_[it - added_secure_type_names_.begin()] + ->GetChannelCredentials(args); + } + } + + std::shared_ptr<ServerCredentials> GetServerCredentials( const TString& type) override { - if (type == grpc::testing::kInsecureCredentialsType) { - return InsecureServerCredentials(); - } else if (type == grpc::testing::kAltsCredentialsType) { - grpc::experimental::AltsServerCredentialsOptions alts_opts; - return grpc::experimental::AltsServerCredentials(alts_opts); - } else if (type == grpc::testing::kTlsCredentialsType) { - SslServerCredentialsOptions ssl_opts; - ssl_opts.pem_root_certs = ""; + if (type == grpc::testing::kInsecureCredentialsType) { + return InsecureServerCredentials(); + } else if (type == grpc::testing::kAltsCredentialsType) { + grpc::experimental::AltsServerCredentialsOptions alts_opts; + return grpc::experimental::AltsServerCredentials(alts_opts); + } else if (type == grpc::testing::kTlsCredentialsType) { + SslServerCredentialsOptions ssl_opts; + ssl_opts.pem_root_certs = ""; if (!custom_server_key_.empty() && !custom_server_cert_.empty()) { SslServerCredentialsOptions::PemKeyCertPair pkcp = { custom_server_key_, custom_server_cert_}; @@ -127,55 +127,55 @@ class DefaultCredentialsProvider : public CredentialsProvider { test_server1_cert}; ssl_opts.pem_key_cert_pairs.push_back(pkcp); } - return SslServerCredentials(ssl_opts); - } else { - std::unique_lock<std::mutex> lock(mu_); - auto it(std::find(added_secure_type_names_.begin(), - added_secure_type_names_.end(), type)); - if (it == added_secure_type_names_.end()) { - gpr_log(GPR_ERROR, "Unsupported credentials type %s.", type.c_str()); - return nullptr; - } - return added_secure_type_providers_[it - added_secure_type_names_.begin()] - ->GetServerCredentials(); - } - } + return SslServerCredentials(ssl_opts); + } else { + std::unique_lock<std::mutex> lock(mu_); + auto it(std::find(added_secure_type_names_.begin(), + added_secure_type_names_.end(), type)); + if (it == added_secure_type_names_.end()) { + gpr_log(GPR_ERROR, "Unsupported credentials type %s.", type.c_str()); + return nullptr; + } + return added_secure_type_providers_[it - added_secure_type_names_.begin()] + ->GetServerCredentials(); + } + } std::vector<TString> GetSecureCredentialsTypeList() override { std::vector<TString> types; - types.push_back(grpc::testing::kTlsCredentialsType); - std::unique_lock<std::mutex> lock(mu_); - for (auto it = added_secure_type_names_.begin(); - it != added_secure_type_names_.end(); it++) { - types.push_back(*it); - } - return types; - } - - private: - std::mutex mu_; + types.push_back(grpc::testing::kTlsCredentialsType); + std::unique_lock<std::mutex> lock(mu_); + for (auto it = added_secure_type_names_.begin(); + it != added_secure_type_names_.end(); it++) { + types.push_back(*it); + } + return types; + } + + private: + std::mutex mu_; std::vector<TString> added_secure_type_names_; - std::vector<std::unique_ptr<CredentialTypeProvider>> - added_secure_type_providers_; + std::vector<std::unique_ptr<CredentialTypeProvider>> + added_secure_type_providers_; TString custom_server_key_; TString custom_server_cert_; -}; - -CredentialsProvider* g_provider = nullptr; - -} // namespace - -CredentialsProvider* GetCredentialsProvider() { - if (g_provider == nullptr) { - g_provider = new DefaultCredentialsProvider; - } - return g_provider; -} - -void SetCredentialsProvider(CredentialsProvider* provider) { - // For now, forbids overriding provider. - GPR_ASSERT(g_provider == nullptr); - g_provider = provider; -} - -} // namespace testing -} // namespace grpc +}; + +CredentialsProvider* g_provider = nullptr; + +} // namespace + +CredentialsProvider* GetCredentialsProvider() { + if (g_provider == nullptr) { + g_provider = new DefaultCredentialsProvider; + } + return g_provider; +} + +void SetCredentialsProvider(CredentialsProvider* provider) { + // For now, forbids overriding provider. + GPR_ASSERT(g_provider == nullptr); + g_provider = provider; +} + +} // namespace testing +} // namespace grpc diff --git a/contrib/libs/grpc/test/cpp/util/test_credentials_provider.h b/contrib/libs/grpc/test/cpp/util/test_credentials_provider.h index acba277ada5..ba8196720e9 100644 --- a/contrib/libs/grpc/test/cpp/util/test_credentials_provider.h +++ b/contrib/libs/grpc/test/cpp/util/test_credentials_provider.h @@ -1,85 +1,85 @@ -/* - * - * Copyright 2016 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. - * - */ - -#ifndef GRPC_TEST_CPP_UTIL_TEST_CREDENTIALS_PROVIDER_H -#define GRPC_TEST_CPP_UTIL_TEST_CREDENTIALS_PROVIDER_H - -#include <memory> - -#include <grpcpp/security/credentials.h> -#include <grpcpp/security/server_credentials.h> -#include <grpcpp/support/channel_arguments.h> - -namespace grpc { -namespace testing { - -const char kInsecureCredentialsType[] = "INSECURE_CREDENTIALS"; -// For real credentials, like tls/ssl, this name should match the AuthContext -// property "transport_security_type". -const char kTlsCredentialsType[] = "ssl"; -const char kAltsCredentialsType[] = "alts"; +/* + * + * Copyright 2016 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. + * + */ + +#ifndef GRPC_TEST_CPP_UTIL_TEST_CREDENTIALS_PROVIDER_H +#define GRPC_TEST_CPP_UTIL_TEST_CREDENTIALS_PROVIDER_H + +#include <memory> + +#include <grpcpp/security/credentials.h> +#include <grpcpp/security/server_credentials.h> +#include <grpcpp/support/channel_arguments.h> + +namespace grpc { +namespace testing { + +const char kInsecureCredentialsType[] = "INSECURE_CREDENTIALS"; +// For real credentials, like tls/ssl, this name should match the AuthContext +// property "transport_security_type". +const char kTlsCredentialsType[] = "ssl"; +const char kAltsCredentialsType[] = "alts"; const char kGoogleDefaultCredentialsType[] = "google_default_credentials"; - -// Provide test credentials of a particular type. -class CredentialTypeProvider { - public: - virtual ~CredentialTypeProvider() {} - - virtual std::shared_ptr<ChannelCredentials> GetChannelCredentials( - ChannelArguments* args) = 0; - virtual std::shared_ptr<ServerCredentials> GetServerCredentials() = 0; -}; - -// Provide test credentials. Thread-safe. -class CredentialsProvider { - public: - virtual ~CredentialsProvider() {} - - // Add a secure type in addition to the defaults. The default provider has - // (kInsecureCredentialsType, kTlsCredentialsType). - virtual void AddSecureType( + +// Provide test credentials of a particular type. +class CredentialTypeProvider { + public: + virtual ~CredentialTypeProvider() {} + + virtual std::shared_ptr<ChannelCredentials> GetChannelCredentials( + ChannelArguments* args) = 0; + virtual std::shared_ptr<ServerCredentials> GetServerCredentials() = 0; +}; + +// Provide test credentials. Thread-safe. +class CredentialsProvider { + public: + virtual ~CredentialsProvider() {} + + // Add a secure type in addition to the defaults. The default provider has + // (kInsecureCredentialsType, kTlsCredentialsType). + virtual void AddSecureType( const TString& type, - std::unique_ptr<CredentialTypeProvider> type_provider) = 0; - - // Provide channel credentials according to the given type. Alter the channel - // arguments if needed. Return nullptr if type is not registered. - virtual std::shared_ptr<ChannelCredentials> GetChannelCredentials( + std::unique_ptr<CredentialTypeProvider> type_provider) = 0; + + // Provide channel credentials according to the given type. Alter the channel + // arguments if needed. Return nullptr if type is not registered. + virtual std::shared_ptr<ChannelCredentials> GetChannelCredentials( const TString& type, ChannelArguments* args) = 0; - - // Provide server credentials according to the given type. - // Return nullptr if type is not registered. - virtual std::shared_ptr<ServerCredentials> GetServerCredentials( + + // Provide server credentials according to the given type. + // Return nullptr if type is not registered. + virtual std::shared_ptr<ServerCredentials> GetServerCredentials( const TString& type) = 0; - - // Provide a list of secure credentials type. + + // Provide a list of secure credentials type. virtual std::vector<TString> GetSecureCredentialsTypeList() = 0; -}; - -// Get the current provider. Create a default one if not set. -// Not thread-safe. -CredentialsProvider* GetCredentialsProvider(); - -// Set the global provider. Takes ownership. The previous set provider will be -// destroyed. -// Not thread-safe. -void SetCredentialsProvider(CredentialsProvider* provider); - -} // namespace testing -} // namespace grpc - -#endif // GRPC_TEST_CPP_UTIL_TEST_CREDENTIALS_PROVIDER_H +}; + +// Get the current provider. Create a default one if not set. +// Not thread-safe. +CredentialsProvider* GetCredentialsProvider(); + +// Set the global provider. Takes ownership. The previous set provider will be +// destroyed. +// Not thread-safe. +void SetCredentialsProvider(CredentialsProvider* provider); + +} // namespace testing +} // namespace grpc + +#endif // GRPC_TEST_CPP_UTIL_TEST_CREDENTIALS_PROVIDER_H diff --git a/contrib/libs/grpc/test/cpp/util/time_test.cc b/contrib/libs/grpc/test/cpp/util/time_test.cc index bcbfa14f94f..2d68bd993a9 100644 --- a/contrib/libs/grpc/test/cpp/util/time_test.cc +++ b/contrib/libs/grpc/test/cpp/util/time_test.cc @@ -1,72 +1,72 @@ -/* - * - * 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. - * - */ - -#include <grpc/support/time.h> -#include <grpcpp/support/time.h> -#include <gtest/gtest.h> - +/* + * + * 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. + * + */ + +#include <grpc/support/time.h> +#include <grpcpp/support/time.h> +#include <gtest/gtest.h> + #include "test/core/util/test_config.h" -using std::chrono::duration_cast; -using std::chrono::microseconds; -using std::chrono::system_clock; - -namespace grpc { -namespace { - -class TimeTest : public ::testing::Test {}; - -TEST_F(TimeTest, AbsolutePointTest) { - int64_t us = 10000000L; - gpr_timespec ts = gpr_time_from_micros(us, GPR_TIMESPAN); - ts.clock_type = GPR_CLOCK_REALTIME; - system_clock::time_point tp{microseconds(us)}; - system_clock::time_point tp_converted = Timespec2Timepoint(ts); - gpr_timespec ts_converted; - Timepoint2Timespec(tp_converted, &ts_converted); - EXPECT_TRUE(ts.tv_sec == ts_converted.tv_sec); - EXPECT_TRUE(ts.tv_nsec == ts_converted.tv_nsec); - system_clock::time_point tp_converted_2 = Timespec2Timepoint(ts_converted); - EXPECT_TRUE(tp == tp_converted); - EXPECT_TRUE(tp == tp_converted_2); -} - -// gpr_inf_future is treated specially and mapped to/from time_point::max() -TEST_F(TimeTest, InfFuture) { - EXPECT_EQ(system_clock::time_point::max(), - Timespec2Timepoint(gpr_inf_future(GPR_CLOCK_REALTIME))); - gpr_timespec from_time_point_max; - Timepoint2Timespec(system_clock::time_point::max(), &from_time_point_max); - EXPECT_EQ( - 0, gpr_time_cmp(gpr_inf_future(GPR_CLOCK_REALTIME), from_time_point_max)); - // This will cause an overflow - Timepoint2Timespec( - std::chrono::time_point<system_clock, std::chrono::seconds>::max(), - &from_time_point_max); - EXPECT_EQ( - 0, gpr_time_cmp(gpr_inf_future(GPR_CLOCK_REALTIME), from_time_point_max)); -} - -} // namespace -} // namespace grpc - -int main(int argc, char** argv) { +using std::chrono::duration_cast; +using std::chrono::microseconds; +using std::chrono::system_clock; + +namespace grpc { +namespace { + +class TimeTest : public ::testing::Test {}; + +TEST_F(TimeTest, AbsolutePointTest) { + int64_t us = 10000000L; + gpr_timespec ts = gpr_time_from_micros(us, GPR_TIMESPAN); + ts.clock_type = GPR_CLOCK_REALTIME; + system_clock::time_point tp{microseconds(us)}; + system_clock::time_point tp_converted = Timespec2Timepoint(ts); + gpr_timespec ts_converted; + Timepoint2Timespec(tp_converted, &ts_converted); + EXPECT_TRUE(ts.tv_sec == ts_converted.tv_sec); + EXPECT_TRUE(ts.tv_nsec == ts_converted.tv_nsec); + system_clock::time_point tp_converted_2 = Timespec2Timepoint(ts_converted); + EXPECT_TRUE(tp == tp_converted); + EXPECT_TRUE(tp == tp_converted_2); +} + +// gpr_inf_future is treated specially and mapped to/from time_point::max() +TEST_F(TimeTest, InfFuture) { + EXPECT_EQ(system_clock::time_point::max(), + Timespec2Timepoint(gpr_inf_future(GPR_CLOCK_REALTIME))); + gpr_timespec from_time_point_max; + Timepoint2Timespec(system_clock::time_point::max(), &from_time_point_max); + EXPECT_EQ( + 0, gpr_time_cmp(gpr_inf_future(GPR_CLOCK_REALTIME), from_time_point_max)); + // This will cause an overflow + Timepoint2Timespec( + std::chrono::time_point<system_clock, std::chrono::seconds>::max(), + &from_time_point_max); + EXPECT_EQ( + 0, gpr_time_cmp(gpr_inf_future(GPR_CLOCK_REALTIME), from_time_point_max)); +} + +} // namespace +} // namespace grpc + +int main(int argc, char** argv) { grpc::testing::TestEnvironment env(argc, argv); - ::testing::InitGoogleTest(&argc, argv); - return RUN_ALL_TESTS(); -} + ::testing::InitGoogleTest(&argc, argv); + return RUN_ALL_TESTS(); +} diff --git a/contrib/libs/grpc/test/cpp/util/ya.make b/contrib/libs/grpc/test/cpp/util/ya.make index f043cc5b146..b475855d316 100644 --- a/contrib/libs/grpc/test/cpp/util/ya.make +++ b/contrib/libs/grpc/test/cpp/util/ya.make @@ -1,39 +1,39 @@ -LIBRARY() - +LIBRARY() + LICENSE(Apache-2.0) LICENSE_TEXTS(.yandex_meta/licenses.list.txt) - + OWNER(orivej) -PEERDIR( - contrib/libs/gflags +PEERDIR( + contrib/libs/gflags contrib/libs/protoc contrib/libs/grpc/src/proto/grpc/reflection/v1alpha contrib/restricted/googletest/googlemock contrib/restricted/googletest/googletest -) - +) + ADDINCL( ${ARCADIA_BUILD_ROOT}/contrib/libs/grpc contrib/libs/grpc ) - -NO_COMPILER_WARNINGS() - -SRCS( + +NO_COMPILER_WARNINGS() + +SRCS( byte_buffer_proto_helper.cc - # grpc_cli_libs: - cli_call.cc - cli_credentials.cc - grpc_tool.cc - proto_file_parser.cc - service_describer.cc + # grpc_cli_libs: + cli_call.cc + cli_credentials.cc + grpc_tool.cc + proto_file_parser.cc + service_describer.cc string_ref_helper.cc - # grpc++_proto_reflection_desc_db: - proto_reflection_descriptor_database.cc - # grpc++_test_config: - test_config_cc.cc -) - -END() + # grpc++_proto_reflection_desc_db: + proto_reflection_descriptor_database.cc + # grpc++_test_config: + test_config_cc.cc +) + +END() |