3 * Copyright 2018 gRPC authors.
5 * Licensed under the Apache License, Version 2.0 (the "License");
6 * you may not use this file except in compliance with the License.
7 * You may obtain a copy of the License at
9 * http://www.apache.org/licenses/LICENSE-2.0
11 * Unless required by applicable law or agreed to in writing, software
12 * distributed under the License is distributed on an "AS IS" BASIS,
13 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14 * See the License for the specific language governing permissions and
15 * limitations under the License.
25 #include <grpcpp/channel.h>
26 #include <grpcpp/client_context.h>
27 #include <grpcpp/create_channel.h>
28 #include <grpcpp/generic/generic_stub.h>
29 #include <grpcpp/impl/codegen/proto_utils.h>
30 #include <grpcpp/server.h>
31 #include <grpcpp/server_builder.h>
32 #include <grpcpp/server_context.h>
33 #include <grpcpp/support/client_callback.h>
35 #include "src/core/lib/gpr/env.h"
36 #include "src/core/lib/iomgr/iomgr.h"
37 #include "src/proto/grpc/testing/echo.grpc.pb.h"
38 #include "test/core/util/port.h"
39 #include "test/core/util/test_config.h"
40 #include "test/cpp/end2end/interceptors_util.h"
41 #include "test/cpp/end2end/test_service_impl.h"
42 #include "test/cpp/util/byte_buffer_proto_helper.h"
43 #include "test/cpp/util/string_ref_helper.h"
44 #include "test/cpp/util/test_credentials_provider.h"
46 #include <gtest/gtest.h>
48 // MAYBE_SKIP_TEST is a macro to determine if this particular test configuration
49 // should be skipped based on a decision made at SetUp time. In particular, any
50 // callback tests can only be run if the iomgr can run in the background or if
51 // the transport is in-process.
52 #define MAYBE_SKIP_TEST \
63 enum class Protocol { INPROC, TCP };
67 TestScenario(bool serve_callback, Protocol protocol, bool intercept,
68 const grpc::string& creds_type)
69 : callback_server(serve_callback),
71 use_interceptors(intercept),
72 credentials_type(creds_type) {}
76 bool use_interceptors;
77 const grpc::string credentials_type;
80 static std::ostream& operator<<(std::ostream& out,
81 const TestScenario& scenario) {
82 return out << "TestScenario{callback_server="
83 << (scenario.callback_server ? "true" : "false") << ",protocol="
84 << (scenario.protocol == Protocol::INPROC ? "INPROC" : "TCP")
85 << ",intercept=" << (scenario.use_interceptors ? "true" : "false")
86 << ",creds=" << scenario.credentials_type << "}";
89 void TestScenario::Log() const {
90 std::ostringstream out;
92 gpr_log(GPR_DEBUG, "%s", out.str().c_str());
95 class ClientCallbackEnd2endTest
96 : public ::testing::TestWithParam<TestScenario> {
98 ClientCallbackEnd2endTest() { GetParam().Log(); }
100 void SetUp() override {
101 ServerBuilder builder;
103 auto server_creds = GetCredentialsProvider()->GetServerCredentials(
104 GetParam().credentials_type);
105 // TODO(vjpai): Support testing of AuthMetadataProcessor
107 if (GetParam().protocol == Protocol::TCP) {
108 picked_port_ = grpc_pick_unused_port_or_die();
109 server_address_ << "localhost:" << picked_port_;
110 builder.AddListeningPort(server_address_.str(), server_creds);
112 if (!GetParam().callback_server) {
113 builder.RegisterService(&service_);
115 builder.RegisterService(&callback_service_);
118 if (GetParam().use_interceptors) {
120 std::unique_ptr<experimental::ServerInterceptorFactoryInterface>>
122 // Add 20 dummy server interceptors
123 creators.reserve(20);
124 for (auto i = 0; i < 20; i++) {
125 creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
126 new DummyInterceptorFactory()));
128 builder.experimental().SetInterceptorCreators(std::move(creators));
131 server_ = builder.BuildAndStart();
132 is_server_started_ = true;
133 if (GetParam().protocol == Protocol::TCP &&
134 !grpc_iomgr_run_in_background()) {
140 ChannelArguments args;
141 auto channel_creds = GetCredentialsProvider()->GetChannelCredentials(
142 GetParam().credentials_type, &args);
143 switch (GetParam().protocol) {
145 if (!GetParam().use_interceptors) {
146 channel_ = ::grpc::CreateCustomChannel(server_address_.str(),
147 channel_creds, args);
149 channel_ = CreateCustomChannelWithInterceptors(
150 server_address_.str(), channel_creds, args,
151 CreateDummyClientInterceptors());
154 case Protocol::INPROC:
155 if (!GetParam().use_interceptors) {
156 channel_ = server_->InProcessChannel(args);
158 channel_ = server_->experimental().InProcessChannelWithInterceptors(
159 args, CreateDummyClientInterceptors());
165 stub_ = grpc::testing::EchoTestService::NewStub(channel_);
166 generic_stub_.reset(new GenericStub(channel_));
167 DummyInterceptor::Reset();
170 void TearDown() override {
171 if (is_server_started_) {
172 // Although we would normally do an explicit shutdown, the server
173 // should also work correctly with just a destructor call. The regular
174 // end2end test uses explicit shutdown, so let this one just do reset.
177 if (picked_port_ > 0) {
178 grpc_recycle_unused_port(picked_port_);
182 void SendRpcs(int num_rpcs, bool with_binary_metadata) {
183 grpc::string test_string("");
184 for (int i = 0; i < num_rpcs; i++) {
186 EchoResponse response;
187 ClientContext cli_ctx;
189 test_string += "Hello world. ";
190 request.set_message(test_string);
192 if (with_binary_metadata) {
193 request.mutable_param()->set_echo_metadata(true);
194 char bytes[8] = {'\0', '\1', '\2', '\3',
195 '\4', '\5', '\6', static_cast<char>(i)};
196 val = grpc::string(bytes, 8);
197 cli_ctx.AddMetadata("custom-bin", val);
200 cli_ctx.set_compression_algorithm(GRPC_COMPRESS_GZIP);
203 std::condition_variable cv;
205 stub_->experimental_async()->Echo(
206 &cli_ctx, &request, &response,
207 [&cli_ctx, &request, &response, &done, &mu, &cv, val,
208 with_binary_metadata](Status s) {
211 EXPECT_EQ(request.message(), response.message());
212 if (with_binary_metadata) {
214 1u, cli_ctx.GetServerTrailingMetadata().count("custom-bin"));
215 EXPECT_EQ(val, ToString(cli_ctx.GetServerTrailingMetadata()
219 std::lock_guard<std::mutex> l(mu);
223 std::unique_lock<std::mutex> l(mu);
230 void SendRpcsRawReq(int num_rpcs) {
231 grpc::string test_string("Hello raw world.");
233 request.set_message(test_string);
234 std::unique_ptr<ByteBuffer> send_buf = SerializeToByteBuffer(&request);
236 for (int i = 0; i < num_rpcs; i++) {
237 EchoResponse response;
238 ClientContext cli_ctx;
241 std::condition_variable cv;
243 stub_->experimental_async()->Echo(
244 &cli_ctx, send_buf.get(), &response,
245 [&request, &response, &done, &mu, &cv](Status s) {
248 EXPECT_EQ(request.message(), response.message());
249 std::lock_guard<std::mutex> l(mu);
253 std::unique_lock<std::mutex> l(mu);
260 void SendRpcsGeneric(int num_rpcs, bool maybe_except) {
261 const grpc::string kMethodName("/grpc.testing.EchoTestService/Echo");
262 grpc::string test_string("");
263 for (int i = 0; i < num_rpcs; i++) {
265 std::unique_ptr<ByteBuffer> send_buf;
267 ClientContext cli_ctx;
269 test_string += "Hello world. ";
270 request.set_message(test_string);
271 send_buf = SerializeToByteBuffer(&request);
274 std::condition_variable cv;
276 generic_stub_->experimental().UnaryCall(
277 &cli_ctx, kMethodName, send_buf.get(), &recv_buf,
278 [&request, &recv_buf, &done, &mu, &cv, maybe_except](Status s) {
281 EchoResponse response;
282 EXPECT_TRUE(ParseFromByteBuffer(&recv_buf, &response));
283 EXPECT_EQ(request.message(), response.message());
284 std::lock_guard<std::mutex> l(mu);
287 #if GRPC_ALLOW_EXCEPTIONS
292 GPR_ASSERT(!maybe_except);
295 std::unique_lock<std::mutex> l(mu);
302 void SendGenericEchoAsBidi(int num_rpcs, int reuses) {
303 const grpc::string kMethodName("/grpc.testing.EchoTestService/Echo");
304 grpc::string test_string("");
305 for (int i = 0; i < num_rpcs; i++) {
306 test_string += "Hello world. ";
307 class Client : public grpc::experimental::ClientBidiReactor<ByteBuffer,
310 Client(ClientCallbackEnd2endTest* test, const grpc::string& method_name,
311 const grpc::string& test_str, int reuses)
312 : reuses_remaining_(reuses) {
313 activate_ = [this, test, method_name, test_str] {
314 if (reuses_remaining_ > 0) {
315 cli_ctx_.reset(new ClientContext);
317 test->generic_stub_->experimental().PrepareBidiStreamingCall(
318 cli_ctx_.get(), method_name, this);
319 request_.set_message(test_str);
320 send_buf_ = SerializeToByteBuffer(&request_);
321 StartWrite(send_buf_.get());
322 StartRead(&recv_buf_);
325 std::unique_lock<std::mutex> l(mu_);
332 void OnWriteDone(bool /*ok*/) override { StartWritesDone(); }
333 void OnReadDone(bool /*ok*/) override {
334 EchoResponse response;
335 EXPECT_TRUE(ParseFromByteBuffer(&recv_buf_, &response));
336 EXPECT_EQ(request_.message(), response.message());
338 void OnDone(const Status& s) override {
343 std::unique_lock<std::mutex> l(mu_);
349 EchoRequest request_;
350 std::unique_ptr<ByteBuffer> send_buf_;
351 ByteBuffer recv_buf_;
352 std::unique_ptr<ClientContext> cli_ctx_;
353 int reuses_remaining_;
354 std::function<void()> activate_;
356 std::condition_variable cv_;
358 } rpc{this, kMethodName, test_string, reuses};
363 bool do_not_test_{false};
364 bool is_server_started_{false};
366 std::shared_ptr<Channel> channel_;
367 std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
368 std::unique_ptr<grpc::GenericStub> generic_stub_;
369 TestServiceImpl service_;
370 CallbackTestServiceImpl callback_service_;
371 std::unique_ptr<Server> server_;
372 std::ostringstream server_address_;
375 TEST_P(ClientCallbackEnd2endTest, SimpleRpc) {
381 TEST_P(ClientCallbackEnd2endTest, SimpleRpcUnderLockNested) {
384 std::mutex mu1, mu2, mu3;
385 std::condition_variable cv;
387 EchoRequest request1, request2, request3;
388 request1.set_message("Hello locked world1.");
389 request2.set_message("Hello locked world2.");
390 request3.set_message("Hello locked world3.");
391 EchoResponse response1, response2, response3;
392 ClientContext cli_ctx1, cli_ctx2, cli_ctx3;
394 std::lock_guard<std::mutex> l(mu1);
395 stub_->experimental_async()->Echo(
396 &cli_ctx1, &request1, &response1,
397 [this, &mu1, &mu2, &mu3, &cv, &done, &request1, &request2, &request3,
398 &response1, &response2, &response3, &cli_ctx2, &cli_ctx3](Status s1) {
399 std::lock_guard<std::mutex> l1(mu1);
400 EXPECT_TRUE(s1.ok());
401 EXPECT_EQ(request1.message(), response1.message());
402 // start the second level of nesting
403 std::unique_lock<std::mutex> l2(mu2);
404 this->stub_->experimental_async()->Echo(
405 &cli_ctx2, &request2, &response2,
406 [this, &mu2, &mu3, &cv, &done, &request2, &request3, &response2,
407 &response3, &cli_ctx3](Status s2) {
408 std::lock_guard<std::mutex> l2(mu2);
409 EXPECT_TRUE(s2.ok());
410 EXPECT_EQ(request2.message(), response2.message());
411 // start the third level of nesting
412 std::lock_guard<std::mutex> l3(mu3);
413 stub_->experimental_async()->Echo(
414 &cli_ctx3, &request3, &response3,
415 [&mu3, &cv, &done, &request3, &response3](Status s3) {
416 std::lock_guard<std::mutex> l(mu3);
417 EXPECT_TRUE(s3.ok());
418 EXPECT_EQ(request3.message(), response3.message());
426 std::unique_lock<std::mutex> l(mu3);
432 TEST_P(ClientCallbackEnd2endTest, SimpleRpcUnderLock) {
436 std::condition_variable cv;
439 request.set_message("Hello locked world.");
440 EchoResponse response;
441 ClientContext cli_ctx;
443 std::lock_guard<std::mutex> l(mu);
444 stub_->experimental_async()->Echo(
445 &cli_ctx, &request, &response,
446 [&mu, &cv, &done, &request, &response](Status s) {
447 std::lock_guard<std::mutex> l(mu);
449 EXPECT_EQ(request.message(), response.message());
454 std::unique_lock<std::mutex> l(mu);
460 TEST_P(ClientCallbackEnd2endTest, SequentialRpcs) {
466 TEST_P(ClientCallbackEnd2endTest, SequentialRpcsRawReq) {
472 TEST_P(ClientCallbackEnd2endTest, SendClientInitialMetadata) {
475 SimpleRequest request;
476 SimpleResponse response;
477 ClientContext cli_ctx;
479 cli_ctx.AddMetadata(kCheckClientInitialMetadataKey,
480 kCheckClientInitialMetadataVal);
483 std::condition_variable cv;
485 stub_->experimental_async()->CheckClientInitialMetadata(
486 &cli_ctx, &request, &response, [&done, &mu, &cv](Status s) {
489 std::lock_guard<std::mutex> l(mu);
493 std::unique_lock<std::mutex> l(mu);
499 TEST_P(ClientCallbackEnd2endTest, SimpleRpcWithBinaryMetadata) {
505 TEST_P(ClientCallbackEnd2endTest, SequentialRpcsWithVariedBinaryMetadataValue) {
511 TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcs) {
514 SendRpcsGeneric(10, false);
517 TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcsAsBidi) {
520 SendGenericEchoAsBidi(10, 1);
523 TEST_P(ClientCallbackEnd2endTest, SequentialGenericRpcsAsBidiWithReactorReuse) {
526 SendGenericEchoAsBidi(10, 10);
529 #if GRPC_ALLOW_EXCEPTIONS
530 TEST_P(ClientCallbackEnd2endTest, ExceptingRpc) {
533 SendRpcsGeneric(10, true);
537 TEST_P(ClientCallbackEnd2endTest, MultipleRpcsWithVariedBinaryMetadataValue) {
540 std::vector<std::thread> threads;
542 for (int i = 0; i < 10; ++i) {
543 threads.emplace_back([this] { SendRpcs(10, true); });
545 for (int i = 0; i < 10; ++i) {
550 TEST_P(ClientCallbackEnd2endTest, MultipleRpcs) {
553 std::vector<std::thread> threads;
555 for (int i = 0; i < 10; ++i) {
556 threads.emplace_back([this] { SendRpcs(10, false); });
558 for (int i = 0; i < 10; ++i) {
563 TEST_P(ClientCallbackEnd2endTest, CancelRpcBeforeStart) {
567 EchoResponse response;
568 ClientContext context;
569 request.set_message("hello");
573 std::condition_variable cv;
575 stub_->experimental_async()->Echo(
576 &context, &request, &response, [&response, &done, &mu, &cv](Status s) {
577 EXPECT_EQ("", response.message());
578 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
579 std::lock_guard<std::mutex> l(mu);
583 std::unique_lock<std::mutex> l(mu);
587 if (GetParam().use_interceptors) {
588 EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel());
592 TEST_P(ClientCallbackEnd2endTest, RequestEchoServerCancel) {
596 EchoResponse response;
597 ClientContext context;
598 request.set_message("hello");
599 context.AddMetadata(kServerTryCancelRequest,
600 grpc::to_string(CANCEL_BEFORE_PROCESSING));
603 std::condition_variable cv;
605 stub_->experimental_async()->Echo(
606 &context, &request, &response, [&done, &mu, &cv](Status s) {
607 EXPECT_FALSE(s.ok());
608 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
609 std::lock_guard<std::mutex> l(mu);
613 std::unique_lock<std::mutex> l(mu);
619 struct ClientCancelInfo {
621 int ops_before_cancel;
623 ClientCancelInfo() : cancel{false} {}
624 explicit ClientCancelInfo(int ops) : cancel{true}, ops_before_cancel{ops} {}
627 class WriteClient : public grpc::experimental::ClientWriteReactor<EchoRequest> {
629 WriteClient(grpc::testing::EchoTestService::Stub* stub,
630 ServerTryCancelRequestPhase server_try_cancel,
631 int num_msgs_to_send, ClientCancelInfo client_cancel = {})
632 : server_try_cancel_(server_try_cancel),
633 num_msgs_to_send_(num_msgs_to_send),
634 client_cancel_{client_cancel} {
635 grpc::string msg{"Hello server."};
636 for (int i = 0; i < num_msgs_to_send; i++) {
639 if (server_try_cancel != DO_NOT_CANCEL) {
640 // Send server_try_cancel value in the client metadata
641 context_.AddMetadata(kServerTryCancelRequest,
642 grpc::to_string(server_try_cancel));
644 context_.set_initial_metadata_corked(true);
645 stub->experimental_async()->RequestStream(&context_, &response_, this);
647 request_.set_message(msg);
650 void OnWriteDone(bool ok) override {
656 void OnDone(const Status& s) override {
657 gpr_log(GPR_INFO, "Sent %d messages", num_msgs_sent_);
659 (client_cancel_.cancel)
660 ? std::min(num_msgs_to_send_, client_cancel_.ops_before_cancel)
662 switch (server_try_cancel_) {
663 case CANCEL_BEFORE_PROCESSING:
664 case CANCEL_DURING_PROCESSING:
665 // If the RPC is canceled by server before / during messages from the
666 // client, it means that the client most likely did not get a chance to
667 // send all the messages it wanted to send. i.e num_msgs_sent <=
669 EXPECT_LE(num_msgs_sent_, num_to_send);
672 case CANCEL_AFTER_PROCESSING:
673 // If the RPC was not canceled or canceled after all messages were read
674 // by the server, the client did get a chance to send all its messages
675 EXPECT_EQ(num_msgs_sent_, num_to_send);
681 if ((server_try_cancel_ == DO_NOT_CANCEL) && !client_cancel_.cancel) {
683 EXPECT_EQ(response_.message(), desired_);
685 EXPECT_FALSE(s.ok());
686 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
688 std::unique_lock<std::mutex> l(mu_);
693 std::unique_lock<std::mutex> l(mu_);
701 if (client_cancel_.cancel &&
702 num_msgs_sent_ == client_cancel_.ops_before_cancel) {
703 context_.TryCancel();
704 } else if (num_msgs_to_send_ > num_msgs_sent_ + 1) {
705 StartWrite(&request_);
706 } else if (num_msgs_to_send_ == num_msgs_sent_ + 1) {
707 StartWriteLast(&request_, WriteOptions());
710 EchoRequest request_;
711 EchoResponse response_;
712 ClientContext context_;
713 const ServerTryCancelRequestPhase server_try_cancel_;
714 int num_msgs_sent_{0};
715 const int num_msgs_to_send_;
716 grpc::string desired_;
717 const ClientCancelInfo client_cancel_;
719 std::condition_variable cv_;
723 TEST_P(ClientCallbackEnd2endTest, RequestStream) {
726 WriteClient test{stub_.get(), DO_NOT_CANCEL, 3};
728 // Make sure that the server interceptors were not notified to cancel
729 if (GetParam().use_interceptors) {
730 EXPECT_EQ(0, DummyInterceptor::GetNumTimesCancel());
734 TEST_P(ClientCallbackEnd2endTest, ClientCancelsRequestStream) {
737 WriteClient test{stub_.get(), DO_NOT_CANCEL, 3, ClientCancelInfo{2}};
739 // Make sure that the server interceptors got the cancel
740 if (GetParam().use_interceptors) {
741 EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel());
745 // Server to cancel before doing reading the request
746 TEST_P(ClientCallbackEnd2endTest, RequestStreamServerCancelBeforeReads) {
749 WriteClient test{stub_.get(), CANCEL_BEFORE_PROCESSING, 1};
751 // Make sure that the server interceptors were notified
752 if (GetParam().use_interceptors) {
753 EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel());
757 // Server to cancel while reading a request from the stream in parallel
758 TEST_P(ClientCallbackEnd2endTest, RequestStreamServerCancelDuringRead) {
761 WriteClient test{stub_.get(), CANCEL_DURING_PROCESSING, 10};
763 // Make sure that the server interceptors were notified
764 if (GetParam().use_interceptors) {
765 EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel());
769 // Server to cancel after reading all the requests but before returning to the
771 TEST_P(ClientCallbackEnd2endTest, RequestStreamServerCancelAfterReads) {
774 WriteClient test{stub_.get(), CANCEL_AFTER_PROCESSING, 4};
776 // Make sure that the server interceptors were notified
777 if (GetParam().use_interceptors) {
778 EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel());
782 TEST_P(ClientCallbackEnd2endTest, UnaryReactor) {
785 class UnaryClient : public grpc::experimental::ClientUnaryReactor {
787 UnaryClient(grpc::testing::EchoTestService::Stub* stub) {
788 cli_ctx_.AddMetadata("key1", "val1");
789 cli_ctx_.AddMetadata("key2", "val2");
790 request_.mutable_param()->set_echo_metadata_initially(true);
791 request_.set_message("Hello metadata");
792 stub->experimental_async()->Echo(&cli_ctx_, &request_, &response_, this);
795 void OnReadInitialMetadataDone(bool ok) override {
797 EXPECT_EQ(1u, cli_ctx_.GetServerInitialMetadata().count("key1"));
800 ToString(cli_ctx_.GetServerInitialMetadata().find("key1")->second));
801 EXPECT_EQ(1u, cli_ctx_.GetServerInitialMetadata().count("key2"));
804 ToString(cli_ctx_.GetServerInitialMetadata().find("key2")->second));
805 initial_metadata_done_ = true;
807 void OnDone(const Status& s) override {
808 EXPECT_TRUE(initial_metadata_done_);
809 EXPECT_EQ(0u, cli_ctx_.GetServerTrailingMetadata().size());
811 EXPECT_EQ(request_.message(), response_.message());
812 std::unique_lock<std::mutex> l(mu_);
817 std::unique_lock<std::mutex> l(mu_);
824 EchoRequest request_;
825 EchoResponse response_;
826 ClientContext cli_ctx_;
828 std::condition_variable cv_;
830 bool initial_metadata_done_{false};
833 UnaryClient test{stub_.get()};
835 // Make sure that the server interceptors were not notified of a cancel
836 if (GetParam().use_interceptors) {
837 EXPECT_EQ(0, DummyInterceptor::GetNumTimesCancel());
841 TEST_P(ClientCallbackEnd2endTest, GenericUnaryReactor) {
844 const grpc::string kMethodName("/grpc.testing.EchoTestService/Echo");
845 class UnaryClient : public grpc::experimental::ClientUnaryReactor {
847 UnaryClient(grpc::GenericStub* stub, const grpc::string& method_name) {
848 cli_ctx_.AddMetadata("key1", "val1");
849 cli_ctx_.AddMetadata("key2", "val2");
850 request_.mutable_param()->set_echo_metadata_initially(true);
851 request_.set_message("Hello metadata");
852 send_buf_ = SerializeToByteBuffer(&request_);
854 stub->experimental().PrepareUnaryCall(&cli_ctx_, method_name,
855 send_buf_.get(), &recv_buf_, this);
858 void OnReadInitialMetadataDone(bool ok) override {
860 EXPECT_EQ(1u, cli_ctx_.GetServerInitialMetadata().count("key1"));
863 ToString(cli_ctx_.GetServerInitialMetadata().find("key1")->second));
864 EXPECT_EQ(1u, cli_ctx_.GetServerInitialMetadata().count("key2"));
867 ToString(cli_ctx_.GetServerInitialMetadata().find("key2")->second));
868 initial_metadata_done_ = true;
870 void OnDone(const Status& s) override {
871 EXPECT_TRUE(initial_metadata_done_);
872 EXPECT_EQ(0u, cli_ctx_.GetServerTrailingMetadata().size());
874 EchoResponse response;
875 EXPECT_TRUE(ParseFromByteBuffer(&recv_buf_, &response));
876 EXPECT_EQ(request_.message(), response.message());
877 std::unique_lock<std::mutex> l(mu_);
882 std::unique_lock<std::mutex> l(mu_);
889 EchoRequest request_;
890 std::unique_ptr<ByteBuffer> send_buf_;
891 ByteBuffer recv_buf_;
892 ClientContext cli_ctx_;
894 std::condition_variable cv_;
896 bool initial_metadata_done_{false};
899 UnaryClient test{generic_stub_.get(), kMethodName};
901 // Make sure that the server interceptors were not notified of a cancel
902 if (GetParam().use_interceptors) {
903 EXPECT_EQ(0, DummyInterceptor::GetNumTimesCancel());
907 class ReadClient : public grpc::experimental::ClientReadReactor<EchoResponse> {
909 ReadClient(grpc::testing::EchoTestService::Stub* stub,
910 ServerTryCancelRequestPhase server_try_cancel,
911 ClientCancelInfo client_cancel = {})
912 : server_try_cancel_(server_try_cancel), client_cancel_{client_cancel} {
913 if (server_try_cancel_ != DO_NOT_CANCEL) {
914 // Send server_try_cancel value in the client metadata
915 context_.AddMetadata(kServerTryCancelRequest,
916 grpc::to_string(server_try_cancel));
918 request_.set_message("Hello client ");
919 stub->experimental_async()->ResponseStream(&context_, &request_, this);
920 if (client_cancel_.cancel &&
921 reads_complete_ == client_cancel_.ops_before_cancel) {
922 context_.TryCancel();
924 // Even if we cancel, read until failure because there might be responses
926 StartRead(&response_);
929 void OnReadDone(bool ok) override {
931 if (server_try_cancel_ == DO_NOT_CANCEL && !client_cancel_.cancel) {
932 EXPECT_EQ(reads_complete_, kServerDefaultResponseStreamsToSend);
935 EXPECT_LE(reads_complete_, kServerDefaultResponseStreamsToSend);
936 EXPECT_EQ(response_.message(),
937 request_.message() + grpc::to_string(reads_complete_));
939 if (client_cancel_.cancel &&
940 reads_complete_ == client_cancel_.ops_before_cancel) {
941 context_.TryCancel();
943 // Even if we cancel, read until failure because there might be responses
945 StartRead(&response_);
948 void OnDone(const Status& s) override {
949 gpr_log(GPR_INFO, "Read %d messages", reads_complete_);
950 switch (server_try_cancel_) {
952 if (!client_cancel_.cancel || client_cancel_.ops_before_cancel >
953 kServerDefaultResponseStreamsToSend) {
955 EXPECT_EQ(reads_complete_, kServerDefaultResponseStreamsToSend);
957 EXPECT_GE(reads_complete_, client_cancel_.ops_before_cancel);
958 EXPECT_LE(reads_complete_, kServerDefaultResponseStreamsToSend);
959 // Status might be ok or cancelled depending on whether server
960 // sent status before client cancel went through
962 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
966 case CANCEL_BEFORE_PROCESSING:
967 EXPECT_FALSE(s.ok());
968 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
969 EXPECT_EQ(reads_complete_, 0);
971 case CANCEL_DURING_PROCESSING:
972 case CANCEL_AFTER_PROCESSING:
973 // If server canceled while writing messages, client must have read
974 // less than or equal to the expected number of messages. Even if the
975 // server canceled after writing all messages, the RPC may be canceled
976 // before the Client got a chance to read all the messages.
977 EXPECT_FALSE(s.ok());
978 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
979 EXPECT_LE(reads_complete_, kServerDefaultResponseStreamsToSend);
984 std::unique_lock<std::mutex> l(mu_);
989 std::unique_lock<std::mutex> l(mu_);
996 EchoRequest request_;
997 EchoResponse response_;
998 ClientContext context_;
999 const ServerTryCancelRequestPhase server_try_cancel_;
1000 int reads_complete_{0};
1001 const ClientCancelInfo client_cancel_;
1003 std::condition_variable cv_;
1007 TEST_P(ClientCallbackEnd2endTest, ResponseStream) {
1010 ReadClient test{stub_.get(), DO_NOT_CANCEL};
1012 // Make sure that the server interceptors were not notified of a cancel
1013 if (GetParam().use_interceptors) {
1014 EXPECT_EQ(0, DummyInterceptor::GetNumTimesCancel());
1018 TEST_P(ClientCallbackEnd2endTest, ClientCancelsResponseStream) {
1021 ReadClient test{stub_.get(), DO_NOT_CANCEL, ClientCancelInfo{2}};
1023 // Because cancel in this case races with server finish, we can't be sure that
1024 // server interceptors even see cancellation
1027 // Server to cancel before sending any response messages
1028 TEST_P(ClientCallbackEnd2endTest, ResponseStreamServerCancelBefore) {
1031 ReadClient test{stub_.get(), CANCEL_BEFORE_PROCESSING};
1033 // Make sure that the server interceptors were notified
1034 if (GetParam().use_interceptors) {
1035 EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel());
1039 // Server to cancel while writing a response to the stream in parallel
1040 TEST_P(ClientCallbackEnd2endTest, ResponseStreamServerCancelDuring) {
1043 ReadClient test{stub_.get(), CANCEL_DURING_PROCESSING};
1045 // Make sure that the server interceptors were notified
1046 if (GetParam().use_interceptors) {
1047 EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel());
1051 // Server to cancel after writing all the respones to the stream but before
1052 // returning to the client
1053 TEST_P(ClientCallbackEnd2endTest, ResponseStreamServerCancelAfter) {
1056 ReadClient test{stub_.get(), CANCEL_AFTER_PROCESSING};
1058 // Make sure that the server interceptors were notified
1059 if (GetParam().use_interceptors) {
1060 EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel());
1065 : public grpc::experimental::ClientBidiReactor<EchoRequest, EchoResponse> {
1067 BidiClient(grpc::testing::EchoTestService::Stub* stub,
1068 ServerTryCancelRequestPhase server_try_cancel,
1069 int num_msgs_to_send, ClientCancelInfo client_cancel = {})
1070 : server_try_cancel_(server_try_cancel),
1071 msgs_to_send_{num_msgs_to_send},
1072 client_cancel_{client_cancel} {
1073 if (server_try_cancel_ != DO_NOT_CANCEL) {
1074 // Send server_try_cancel value in the client metadata
1075 context_.AddMetadata(kServerTryCancelRequest,
1076 grpc::to_string(server_try_cancel));
1078 request_.set_message("Hello fren ");
1079 stub->experimental_async()->BidiStream(&context_, this);
1081 StartRead(&response_);
1084 void OnReadDone(bool ok) override {
1086 if (server_try_cancel_ == DO_NOT_CANCEL) {
1087 if (!client_cancel_.cancel) {
1088 EXPECT_EQ(reads_complete_, msgs_to_send_);
1090 EXPECT_LE(reads_complete_, writes_complete_);
1094 EXPECT_LE(reads_complete_, msgs_to_send_);
1095 EXPECT_EQ(response_.message(), request_.message());
1097 StartRead(&response_);
1100 void OnWriteDone(bool ok) override {
1101 if (server_try_cancel_ == DO_NOT_CANCEL) {
1109 void OnDone(const Status& s) override {
1110 gpr_log(GPR_INFO, "Sent %d messages", writes_complete_);
1111 gpr_log(GPR_INFO, "Read %d messages", reads_complete_);
1112 switch (server_try_cancel_) {
1114 if (!client_cancel_.cancel ||
1115 client_cancel_.ops_before_cancel > msgs_to_send_) {
1116 EXPECT_TRUE(s.ok());
1117 EXPECT_EQ(writes_complete_, msgs_to_send_);
1118 EXPECT_EQ(reads_complete_, writes_complete_);
1120 EXPECT_FALSE(s.ok());
1121 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
1122 EXPECT_EQ(writes_complete_, client_cancel_.ops_before_cancel);
1123 EXPECT_LE(reads_complete_, writes_complete_);
1126 case CANCEL_BEFORE_PROCESSING:
1127 EXPECT_FALSE(s.ok());
1128 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
1129 // The RPC is canceled before the server did any work or returned any
1130 // reads, but it's possible that some writes took place first from the
1132 EXPECT_LE(writes_complete_, msgs_to_send_);
1133 EXPECT_EQ(reads_complete_, 0);
1135 case CANCEL_DURING_PROCESSING:
1136 EXPECT_FALSE(s.ok());
1137 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
1138 EXPECT_LE(writes_complete_, msgs_to_send_);
1139 EXPECT_LE(reads_complete_, writes_complete_);
1141 case CANCEL_AFTER_PROCESSING:
1142 EXPECT_FALSE(s.ok());
1143 EXPECT_EQ(grpc::StatusCode::CANCELLED, s.error_code());
1144 EXPECT_EQ(writes_complete_, msgs_to_send_);
1145 // The Server canceled after reading the last message and after writing
1146 // the message to the client. However, the RPC cancellation might have
1147 // taken effect before the client actually read the response.
1148 EXPECT_LE(reads_complete_, writes_complete_);
1153 std::unique_lock<std::mutex> l(mu_);
1158 std::unique_lock<std::mutex> l(mu_);
1166 if (client_cancel_.cancel &&
1167 writes_complete_ == client_cancel_.ops_before_cancel) {
1168 context_.TryCancel();
1169 } else if (writes_complete_ == msgs_to_send_) {
1172 StartWrite(&request_);
1175 EchoRequest request_;
1176 EchoResponse response_;
1177 ClientContext context_;
1178 const ServerTryCancelRequestPhase server_try_cancel_;
1179 int reads_complete_{0};
1180 int writes_complete_{0};
1181 const int msgs_to_send_;
1182 const ClientCancelInfo client_cancel_;
1184 std::condition_variable cv_;
1188 TEST_P(ClientCallbackEnd2endTest, BidiStream) {
1191 BidiClient test{stub_.get(), DO_NOT_CANCEL,
1192 kServerDefaultResponseStreamsToSend};
1194 // Make sure that the server interceptors were not notified of a cancel
1195 if (GetParam().use_interceptors) {
1196 EXPECT_EQ(0, DummyInterceptor::GetNumTimesCancel());
1200 TEST_P(ClientCallbackEnd2endTest, ClientCancelsBidiStream) {
1203 BidiClient test{stub_.get(), DO_NOT_CANCEL,
1204 kServerDefaultResponseStreamsToSend, ClientCancelInfo{2}};
1206 // Make sure that the server interceptors were notified of a cancel
1207 if (GetParam().use_interceptors) {
1208 EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel());
1212 // Server to cancel before reading/writing any requests/responses on the stream
1213 TEST_P(ClientCallbackEnd2endTest, BidiStreamServerCancelBefore) {
1216 BidiClient test{stub_.get(), CANCEL_BEFORE_PROCESSING, 2};
1218 // Make sure that the server interceptors were notified
1219 if (GetParam().use_interceptors) {
1220 EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel());
1224 // Server to cancel while reading/writing requests/responses on the stream in
1226 TEST_P(ClientCallbackEnd2endTest, BidiStreamServerCancelDuring) {
1229 BidiClient test{stub_.get(), CANCEL_DURING_PROCESSING, 10};
1231 // Make sure that the server interceptors were notified
1232 if (GetParam().use_interceptors) {
1233 EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel());
1237 // Server to cancel after reading/writing all requests/responses on the stream
1238 // but before returning to the client
1239 TEST_P(ClientCallbackEnd2endTest, BidiStreamServerCancelAfter) {
1242 BidiClient test{stub_.get(), CANCEL_AFTER_PROCESSING, 5};
1244 // Make sure that the server interceptors were notified
1245 if (GetParam().use_interceptors) {
1246 EXPECT_EQ(20, DummyInterceptor::GetNumTimesCancel());
1250 TEST_P(ClientCallbackEnd2endTest, SimultaneousReadAndWritesDone) {
1253 class Client : public grpc::experimental::ClientBidiReactor<EchoRequest,
1256 Client(grpc::testing::EchoTestService::Stub* stub) {
1257 request_.set_message("Hello bidi ");
1258 stub->experimental_async()->BidiStream(&context_, this);
1259 StartWrite(&request_);
1262 void OnReadDone(bool ok) override {
1264 EXPECT_EQ(response_.message(), request_.message());
1266 void OnWriteDone(bool ok) override {
1268 // Now send out the simultaneous Read and WritesDone
1270 StartRead(&response_);
1272 void OnDone(const Status& s) override {
1273 EXPECT_TRUE(s.ok());
1274 EXPECT_EQ(response_.message(), request_.message());
1275 std::unique_lock<std::mutex> l(mu_);
1280 std::unique_lock<std::mutex> l(mu_);
1287 EchoRequest request_;
1288 EchoResponse response_;
1289 ClientContext context_;
1291 std::condition_variable cv_;
1293 } test{stub_.get()};
1298 TEST_P(ClientCallbackEnd2endTest, UnimplementedRpc) {
1300 ChannelArguments args;
1301 const auto& channel_creds = GetCredentialsProvider()->GetChannelCredentials(
1302 GetParam().credentials_type, &args);
1303 std::shared_ptr<Channel> channel =
1304 (GetParam().protocol == Protocol::TCP)
1305 ? ::grpc::CreateCustomChannel(server_address_.str(), channel_creds,
1307 : server_->InProcessChannel(args);
1308 std::unique_ptr<grpc::testing::UnimplementedEchoService::Stub> stub;
1309 stub = grpc::testing::UnimplementedEchoService::NewStub(channel);
1310 EchoRequest request;
1311 EchoResponse response;
1312 ClientContext cli_ctx;
1313 request.set_message("Hello world.");
1315 std::condition_variable cv;
1317 stub->experimental_async()->Unimplemented(
1318 &cli_ctx, &request, &response, [&done, &mu, &cv](Status s) {
1319 EXPECT_EQ(StatusCode::UNIMPLEMENTED, s.error_code());
1320 EXPECT_EQ("", s.error_message());
1322 std::lock_guard<std::mutex> l(mu);
1326 std::unique_lock<std::mutex> l(mu);
1332 TEST_P(ClientCallbackEnd2endTest,
1333 ResponseStreamExtraReactionFlowReadsUntilDone) {
1336 class ReadAllIncomingDataClient
1337 : public grpc::experimental::ClientReadReactor<EchoResponse> {
1339 ReadAllIncomingDataClient(grpc::testing::EchoTestService::Stub* stub) {
1340 request_.set_message("Hello client ");
1341 stub->experimental_async()->ResponseStream(&context_, &request_, this);
1343 bool WaitForReadDone() {
1344 std::unique_lock<std::mutex> l(mu_);
1345 while (!read_done_) {
1352 std::unique_lock<std::mutex> l(mu_);
1357 const Status& status() {
1358 std::unique_lock<std::mutex> l(mu_);
1363 void OnReadDone(bool ok) override {
1364 std::unique_lock<std::mutex> l(mu_);
1367 read_cv_.notify_one();
1369 void OnDone(const Status& s) override {
1370 std::unique_lock<std::mutex> l(mu_);
1373 done_cv_.notify_one();
1376 EchoRequest request_;
1377 EchoResponse response_;
1378 ClientContext context_;
1379 bool read_ok_ = false;
1380 bool read_done_ = false;
1382 std::condition_variable read_cv_;
1383 std::condition_variable done_cv_;
1386 } client{stub_.get()};
1388 int reads_complete = 0;
1392 EchoResponse response;
1393 bool read_ok = true;
1395 client.StartRead(&response);
1396 read_ok = client.WaitForReadDone();
1401 client.RemoveHold();
1404 EXPECT_EQ(kServerDefaultResponseStreamsToSend, reads_complete);
1405 EXPECT_EQ(client.status().error_code(), grpc::StatusCode::OK);
1408 std::vector<TestScenario> CreateTestScenarios(bool test_insecure) {
1409 #if TARGET_OS_IPHONE
1410 // Workaround Apple CFStream bug
1411 gpr_setenv("grpc_cfstream", "0");
1414 std::vector<TestScenario> scenarios;
1415 std::vector<grpc::string> credentials_types{
1416 GetCredentialsProvider()->GetSecureCredentialsTypeList()};
1417 auto insec_ok = [] {
1418 // Only allow insecure credentials type when it is registered with the
1419 // provider. User may create providers that do not have insecure.
1420 return GetCredentialsProvider()->GetChannelCredentials(
1421 kInsecureCredentialsType, nullptr) != nullptr;
1423 if (test_insecure && insec_ok()) {
1424 credentials_types.push_back(kInsecureCredentialsType);
1426 GPR_ASSERT(!credentials_types.empty());
1428 bool barr[]{false, true};
1429 Protocol parr[]{Protocol::INPROC, Protocol::TCP};
1430 for (Protocol p : parr) {
1431 for (const auto& cred : credentials_types) {
1432 // TODO(vjpai): Test inproc with secure credentials when feasible
1433 if (p == Protocol::INPROC &&
1434 (cred != kInsecureCredentialsType || !insec_ok())) {
1437 for (bool callback_server : barr) {
1438 for (bool use_interceptors : barr) {
1439 scenarios.emplace_back(callback_server, p, use_interceptors, cred);
1447 INSTANTIATE_TEST_SUITE_P(ClientCallbackEnd2endTest, ClientCallbackEnd2endTest,
1448 ::testing::ValuesIn(CreateTestScenarios(true)));
1451 } // namespace testing
1454 int main(int argc, char** argv) {
1455 ::testing::InitGoogleTest(&argc, argv);
1456 grpc::testing::TestEnvironment env(argc, argv);
1458 int ret = RUN_ALL_TESTS();