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.
22 #include <grpcpp/channel.h>
23 #include <grpcpp/client_context.h>
24 #include <grpcpp/create_channel.h>
25 #include <grpcpp/generic/generic_stub.h>
26 #include <grpcpp/impl/codegen/proto_utils.h>
27 #include <grpcpp/server.h>
28 #include <grpcpp/server_builder.h>
29 #include <grpcpp/server_context.h>
30 #include <grpcpp/support/client_interceptor.h>
32 #include "src/proto/grpc/testing/echo.grpc.pb.h"
33 #include "test/core/util/port.h"
34 #include "test/core/util/test_config.h"
35 #include "test/cpp/end2end/interceptors_util.h"
36 #include "test/cpp/end2end/test_service_impl.h"
37 #include "test/cpp/util/byte_buffer_proto_helper.h"
38 #include "test/cpp/util/string_ref_helper.h"
40 #include <gtest/gtest.h>
46 /* Hijacks Echo RPC and fills in the expected values */
47 class HijackingInterceptor : public experimental::Interceptor {
49 HijackingInterceptor(experimental::ClientRpcInfo* info) {
51 // Make sure it is the right method
52 EXPECT_EQ(strcmp("/grpc.testing.EchoTestService/Echo", info->method()), 0);
53 EXPECT_EQ(info->type(), experimental::ClientRpcInfo::Type::UNARY);
56 virtual void Intercept(experimental::InterceptorBatchMethods* methods) {
58 if (methods->QueryInterceptionHookPoint(
59 experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) {
60 auto* map = methods->GetSendInitialMetadata();
61 // Check that we can see the test metadata
62 ASSERT_EQ(map->size(), static_cast<unsigned>(1));
63 auto iterator = map->begin();
64 EXPECT_EQ("testkey", iterator->first);
65 EXPECT_EQ("testvalue", iterator->second);
68 if (methods->QueryInterceptionHookPoint(
69 experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) {
71 auto* buffer = methods->GetSerializedSendMessage();
72 auto copied_buffer = *buffer;
74 SerializationTraits<EchoRequest>::Deserialize(&copied_buffer, &req)
76 EXPECT_EQ(req.message(), "Hello");
78 if (methods->QueryInterceptionHookPoint(
79 experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) {
80 // Got nothing to do here for now
82 if (methods->QueryInterceptionHookPoint(
83 experimental::InterceptionHookPoints::POST_RECV_INITIAL_METADATA)) {
84 auto* map = methods->GetRecvInitialMetadata();
85 // Got nothing better to do here for now
86 EXPECT_EQ(map->size(), static_cast<unsigned>(0));
88 if (methods->QueryInterceptionHookPoint(
89 experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) {
91 static_cast<EchoResponse*>(methods->GetRecvMessage());
92 // Check that we got the hijacked message, and re-insert the expected
94 EXPECT_EQ(resp->message(), "Hello1");
95 resp->set_message("Hello");
97 if (methods->QueryInterceptionHookPoint(
98 experimental::InterceptionHookPoints::POST_RECV_STATUS)) {
99 auto* map = methods->GetRecvTrailingMetadata();
101 // Check that we received the metadata as an echo
102 for (const auto& pair : *map) {
103 found = pair.first.starts_with("testkey") &&
104 pair.second.starts_with("testvalue");
107 EXPECT_EQ(found, true);
108 auto* status = methods->GetRecvStatus();
109 EXPECT_EQ(status->ok(), true);
111 if (methods->QueryInterceptionHookPoint(
112 experimental::InterceptionHookPoints::PRE_RECV_INITIAL_METADATA)) {
113 auto* map = methods->GetRecvInitialMetadata();
114 // Got nothing better to do here at the moment
115 EXPECT_EQ(map->size(), static_cast<unsigned>(0));
117 if (methods->QueryInterceptionHookPoint(
118 experimental::InterceptionHookPoints::PRE_RECV_MESSAGE)) {
119 // Insert a different message than expected
121 static_cast<EchoResponse*>(methods->GetRecvMessage());
122 resp->set_message("Hello1");
124 if (methods->QueryInterceptionHookPoint(
125 experimental::InterceptionHookPoints::PRE_RECV_STATUS)) {
126 auto* map = methods->GetRecvTrailingMetadata();
127 // insert the metadata that we want
128 EXPECT_EQ(map->size(), static_cast<unsigned>(0));
129 map->insert(std::make_pair("testkey", "testvalue"));
130 auto* status = methods->GetRecvStatus();
131 *status = Status(StatusCode::OK, "");
141 experimental::ClientRpcInfo* info_;
144 class HijackingInterceptorFactory
145 : public experimental::ClientInterceptorFactoryInterface {
147 virtual experimental::Interceptor* CreateClientInterceptor(
148 experimental::ClientRpcInfo* info) override {
149 return new HijackingInterceptor(info);
153 class HijackingInterceptorMakesAnotherCall : public experimental::Interceptor {
155 HijackingInterceptorMakesAnotherCall(experimental::ClientRpcInfo* info) {
157 // Make sure it is the right method
158 EXPECT_EQ(strcmp("/grpc.testing.EchoTestService/Echo", info->method()), 0);
161 virtual void Intercept(experimental::InterceptorBatchMethods* methods) {
162 if (methods->QueryInterceptionHookPoint(
163 experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) {
164 auto* map = methods->GetSendInitialMetadata();
165 // Check that we can see the test metadata
166 ASSERT_EQ(map->size(), static_cast<unsigned>(1));
167 auto iterator = map->begin();
168 EXPECT_EQ("testkey", iterator->first);
169 EXPECT_EQ("testvalue", iterator->second);
170 // Make a copy of the map
171 metadata_map_ = *map;
173 if (methods->QueryInterceptionHookPoint(
174 experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) {
176 auto* buffer = methods->GetSerializedSendMessage();
177 auto copied_buffer = *buffer;
179 SerializationTraits<EchoRequest>::Deserialize(&copied_buffer, &req)
181 EXPECT_EQ(req.message(), "Hello");
183 stub_ = grpc::testing::EchoTestService::NewStub(
184 methods->GetInterceptedChannel());
185 ctx_.AddMetadata(metadata_map_.begin()->first,
186 metadata_map_.begin()->second);
187 stub_->experimental_async()->Echo(&ctx_, &req_, &resp_,
188 [this, methods](Status s) {
189 EXPECT_EQ(s.ok(), true);
190 EXPECT_EQ(resp_.message(), "Hello");
193 // There isn't going to be any other interesting operation in this batch,
194 // so it is fine to return
197 if (methods->QueryInterceptionHookPoint(
198 experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) {
199 // Got nothing to do here for now
201 if (methods->QueryInterceptionHookPoint(
202 experimental::InterceptionHookPoints::POST_RECV_INITIAL_METADATA)) {
203 auto* map = methods->GetRecvInitialMetadata();
204 // Got nothing better to do here for now
205 EXPECT_EQ(map->size(), static_cast<unsigned>(0));
207 if (methods->QueryInterceptionHookPoint(
208 experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) {
210 static_cast<EchoResponse*>(methods->GetRecvMessage());
211 // Check that we got the hijacked message, and re-insert the expected
213 EXPECT_EQ(resp->message(), "Hello");
215 if (methods->QueryInterceptionHookPoint(
216 experimental::InterceptionHookPoints::POST_RECV_STATUS)) {
217 auto* map = methods->GetRecvTrailingMetadata();
219 // Check that we received the metadata as an echo
220 for (const auto& pair : *map) {
221 found = pair.first.starts_with("testkey") &&
222 pair.second.starts_with("testvalue");
225 EXPECT_EQ(found, true);
226 auto* status = methods->GetRecvStatus();
227 EXPECT_EQ(status->ok(), true);
229 if (methods->QueryInterceptionHookPoint(
230 experimental::InterceptionHookPoints::PRE_RECV_INITIAL_METADATA)) {
231 auto* map = methods->GetRecvInitialMetadata();
232 // Got nothing better to do here at the moment
233 EXPECT_EQ(map->size(), static_cast<unsigned>(0));
235 if (methods->QueryInterceptionHookPoint(
236 experimental::InterceptionHookPoints::PRE_RECV_MESSAGE)) {
237 // Insert a different message than expected
239 static_cast<EchoResponse*>(methods->GetRecvMessage());
240 resp->set_message(resp_.message());
242 if (methods->QueryInterceptionHookPoint(
243 experimental::InterceptionHookPoints::PRE_RECV_STATUS)) {
244 auto* map = methods->GetRecvTrailingMetadata();
245 // insert the metadata that we want
246 EXPECT_EQ(map->size(), static_cast<unsigned>(0));
247 map->insert(std::make_pair("testkey", "testvalue"));
248 auto* status = methods->GetRecvStatus();
249 *status = Status(StatusCode::OK, "");
256 experimental::ClientRpcInfo* info_;
257 std::multimap<grpc::string, grpc::string> metadata_map_;
261 std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
264 class HijackingInterceptorMakesAnotherCallFactory
265 : public experimental::ClientInterceptorFactoryInterface {
267 virtual experimental::Interceptor* CreateClientInterceptor(
268 experimental::ClientRpcInfo* info) override {
269 return new HijackingInterceptorMakesAnotherCall(info);
273 class BidiStreamingRpcHijackingInterceptor : public experimental::Interceptor {
275 BidiStreamingRpcHijackingInterceptor(experimental::ClientRpcInfo* info) {
279 virtual void Intercept(experimental::InterceptorBatchMethods* methods) {
281 if (methods->QueryInterceptionHookPoint(
282 experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) {
283 CheckMetadata(*methods->GetSendInitialMetadata(), "testkey", "testvalue");
286 if (methods->QueryInterceptionHookPoint(
287 experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) {
289 auto* buffer = methods->GetSerializedSendMessage();
290 auto copied_buffer = *buffer;
292 SerializationTraits<EchoRequest>::Deserialize(&copied_buffer, &req)
294 EXPECT_EQ(req.message().find("Hello"), 0u);
297 if (methods->QueryInterceptionHookPoint(
298 experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) {
299 // Got nothing to do here for now
301 if (methods->QueryInterceptionHookPoint(
302 experimental::InterceptionHookPoints::POST_RECV_STATUS)) {
303 CheckMetadata(*methods->GetRecvTrailingMetadata(), "testkey",
305 auto* status = methods->GetRecvStatus();
306 EXPECT_EQ(status->ok(), true);
308 if (methods->QueryInterceptionHookPoint(
309 experimental::InterceptionHookPoints::PRE_RECV_MESSAGE)) {
311 static_cast<EchoResponse*>(methods->GetRecvMessage());
312 resp->set_message(msg);
314 if (methods->QueryInterceptionHookPoint(
315 experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) {
316 EXPECT_EQ(static_cast<EchoResponse*>(methods->GetRecvMessage())
321 if (methods->QueryInterceptionHookPoint(
322 experimental::InterceptionHookPoints::PRE_RECV_STATUS)) {
323 auto* map = methods->GetRecvTrailingMetadata();
324 // insert the metadata that we want
325 EXPECT_EQ(map->size(), static_cast<unsigned>(0));
326 map->insert(std::make_pair("testkey", "testvalue"));
327 auto* status = methods->GetRecvStatus();
328 *status = Status(StatusCode::OK, "");
338 experimental::ClientRpcInfo* info_;
342 class ClientStreamingRpcHijackingInterceptor
343 : public experimental::Interceptor {
345 ClientStreamingRpcHijackingInterceptor(experimental::ClientRpcInfo* info) {
348 virtual void Intercept(experimental::InterceptorBatchMethods* methods) {
350 if (methods->QueryInterceptionHookPoint(
351 experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) {
354 if (methods->QueryInterceptionHookPoint(
355 experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) {
357 methods->FailHijackedSendMessage();
360 if (methods->QueryInterceptionHookPoint(
361 experimental::InterceptionHookPoints::POST_SEND_MESSAGE)) {
362 EXPECT_FALSE(got_failed_send_);
363 got_failed_send_ = !methods->GetSendMessageStatus();
365 if (methods->QueryInterceptionHookPoint(
366 experimental::InterceptionHookPoints::PRE_RECV_STATUS)) {
367 auto* status = methods->GetRecvStatus();
368 *status = Status(StatusCode::UNAVAILABLE, "Done sending 10 messages");
377 static bool GotFailedSend() { return got_failed_send_; }
380 experimental::ClientRpcInfo* info_;
382 static bool got_failed_send_;
385 bool ClientStreamingRpcHijackingInterceptor::got_failed_send_ = false;
387 class ClientStreamingRpcHijackingInterceptorFactory
388 : public experimental::ClientInterceptorFactoryInterface {
390 virtual experimental::Interceptor* CreateClientInterceptor(
391 experimental::ClientRpcInfo* info) override {
392 return new ClientStreamingRpcHijackingInterceptor(info);
396 class ServerStreamingRpcHijackingInterceptor
397 : public experimental::Interceptor {
399 ServerStreamingRpcHijackingInterceptor(experimental::ClientRpcInfo* info) {
403 virtual void Intercept(experimental::InterceptorBatchMethods* methods) {
405 if (methods->QueryInterceptionHookPoint(
406 experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) {
407 auto* map = methods->GetSendInitialMetadata();
408 // Check that we can see the test metadata
409 ASSERT_EQ(map->size(), static_cast<unsigned>(1));
410 auto iterator = map->begin();
411 EXPECT_EQ("testkey", iterator->first);
412 EXPECT_EQ("testvalue", iterator->second);
415 if (methods->QueryInterceptionHookPoint(
416 experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) {
418 auto* buffer = methods->GetSerializedSendMessage();
419 auto copied_buffer = *buffer;
421 SerializationTraits<EchoRequest>::Deserialize(&copied_buffer, &req)
423 EXPECT_EQ(req.message(), "Hello");
425 if (methods->QueryInterceptionHookPoint(
426 experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) {
427 // Got nothing to do here for now
429 if (methods->QueryInterceptionHookPoint(
430 experimental::InterceptionHookPoints::POST_RECV_STATUS)) {
431 auto* map = methods->GetRecvTrailingMetadata();
433 // Check that we received the metadata as an echo
434 for (const auto& pair : *map) {
435 found = pair.first.starts_with("testkey") &&
436 pair.second.starts_with("testvalue");
439 EXPECT_EQ(found, true);
440 auto* status = methods->GetRecvStatus();
441 EXPECT_EQ(status->ok(), true);
443 if (methods->QueryInterceptionHookPoint(
444 experimental::InterceptionHookPoints::PRE_RECV_MESSAGE)) {
446 methods->FailHijackedRecvMessage();
449 static_cast<EchoResponse*>(methods->GetRecvMessage());
450 resp->set_message("Hello");
452 if (methods->QueryInterceptionHookPoint(
453 experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) {
454 // Only the last message will be a failure
455 EXPECT_FALSE(got_failed_message_);
456 got_failed_message_ = methods->GetRecvMessage() == nullptr;
458 if (methods->QueryInterceptionHookPoint(
459 experimental::InterceptionHookPoints::PRE_RECV_STATUS)) {
460 auto* map = methods->GetRecvTrailingMetadata();
461 // insert the metadata that we want
462 EXPECT_EQ(map->size(), static_cast<unsigned>(0));
463 map->insert(std::make_pair("testkey", "testvalue"));
464 auto* status = methods->GetRecvStatus();
465 *status = Status(StatusCode::OK, "");
474 static bool GotFailedMessage() { return got_failed_message_; }
477 experimental::ClientRpcInfo* info_;
478 static bool got_failed_message_;
482 bool ServerStreamingRpcHijackingInterceptor::got_failed_message_ = false;
484 class ServerStreamingRpcHijackingInterceptorFactory
485 : public experimental::ClientInterceptorFactoryInterface {
487 virtual experimental::Interceptor* CreateClientInterceptor(
488 experimental::ClientRpcInfo* info) override {
489 return new ServerStreamingRpcHijackingInterceptor(info);
493 class BidiStreamingRpcHijackingInterceptorFactory
494 : public experimental::ClientInterceptorFactoryInterface {
496 virtual experimental::Interceptor* CreateClientInterceptor(
497 experimental::ClientRpcInfo* info) override {
498 return new BidiStreamingRpcHijackingInterceptor(info);
502 class LoggingInterceptor : public experimental::Interceptor {
504 LoggingInterceptor(experimental::ClientRpcInfo* info) { info_ = info; }
506 virtual void Intercept(experimental::InterceptorBatchMethods* methods) {
507 if (methods->QueryInterceptionHookPoint(
508 experimental::InterceptionHookPoints::PRE_SEND_INITIAL_METADATA)) {
509 auto* map = methods->GetSendInitialMetadata();
510 // Check that we can see the test metadata
511 ASSERT_EQ(map->size(), static_cast<unsigned>(1));
512 auto iterator = map->begin();
513 EXPECT_EQ("testkey", iterator->first);
514 EXPECT_EQ("testvalue", iterator->second);
516 if (methods->QueryInterceptionHookPoint(
517 experimental::InterceptionHookPoints::PRE_SEND_MESSAGE)) {
519 EXPECT_EQ(static_cast<const EchoRequest*>(methods->GetSendMessage())
523 auto* buffer = methods->GetSerializedSendMessage();
524 auto copied_buffer = *buffer;
526 SerializationTraits<EchoRequest>::Deserialize(&copied_buffer, &req)
528 EXPECT_TRUE(req.message().find("Hello") == 0u);
530 if (methods->QueryInterceptionHookPoint(
531 experimental::InterceptionHookPoints::PRE_SEND_CLOSE)) {
532 // Got nothing to do here for now
534 if (methods->QueryInterceptionHookPoint(
535 experimental::InterceptionHookPoints::POST_RECV_INITIAL_METADATA)) {
536 auto* map = methods->GetRecvInitialMetadata();
537 // Got nothing better to do here for now
538 EXPECT_EQ(map->size(), static_cast<unsigned>(0));
540 if (methods->QueryInterceptionHookPoint(
541 experimental::InterceptionHookPoints::POST_RECV_MESSAGE)) {
543 static_cast<EchoResponse*>(methods->GetRecvMessage());
544 EXPECT_TRUE(resp->message().find("Hello") == 0u);
546 if (methods->QueryInterceptionHookPoint(
547 experimental::InterceptionHookPoints::POST_RECV_STATUS)) {
548 auto* map = methods->GetRecvTrailingMetadata();
550 // Check that we received the metadata as an echo
551 for (const auto& pair : *map) {
552 found = pair.first.starts_with("testkey") &&
553 pair.second.starts_with("testvalue");
556 EXPECT_EQ(found, true);
557 auto* status = methods->GetRecvStatus();
558 EXPECT_EQ(status->ok(), true);
564 experimental::ClientRpcInfo* info_;
567 class LoggingInterceptorFactory
568 : public experimental::ClientInterceptorFactoryInterface {
570 virtual experimental::Interceptor* CreateClientInterceptor(
571 experimental::ClientRpcInfo* info) override {
572 return new LoggingInterceptor(info);
576 class ClientInterceptorsEnd2endTest : public ::testing::Test {
578 ClientInterceptorsEnd2endTest() {
579 int port = grpc_pick_unused_port_or_die();
581 ServerBuilder builder;
582 server_address_ = "localhost:" + std::to_string(port);
583 builder.AddListeningPort(server_address_, InsecureServerCredentials());
584 builder.RegisterService(&service_);
585 server_ = builder.BuildAndStart();
588 ~ClientInterceptorsEnd2endTest() { server_->Shutdown(); }
590 std::string server_address_;
591 TestServiceImpl service_;
592 std::unique_ptr<Server> server_;
595 TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorLoggingTest) {
596 ChannelArguments args;
597 DummyInterceptor::Reset();
598 std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
600 creators.push_back(std::unique_ptr<LoggingInterceptorFactory>(
601 new LoggingInterceptorFactory()));
602 // Add 20 dummy interceptors
603 for (auto i = 0; i < 20; i++) {
604 creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
605 new DummyInterceptorFactory()));
607 auto channel = experimental::CreateCustomChannelWithInterceptors(
608 server_address_, InsecureChannelCredentials(), args, std::move(creators));
610 // Make sure all 20 dummy interceptors were run
611 EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20);
614 TEST_F(ClientInterceptorsEnd2endTest,
615 LameChannelClientInterceptorHijackingTest) {
616 ChannelArguments args;
617 std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
619 creators.push_back(std::unique_ptr<HijackingInterceptorFactory>(
620 new HijackingInterceptorFactory()));
621 auto channel = experimental::CreateCustomChannelWithInterceptors(
622 server_address_, nullptr, args, std::move(creators));
626 TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorHijackingTest) {
627 ChannelArguments args;
628 DummyInterceptor::Reset();
629 std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
631 // Add 20 dummy interceptors before hijacking interceptor
632 creators.reserve(20);
633 for (auto i = 0; i < 20; i++) {
634 creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
635 new DummyInterceptorFactory()));
637 creators.push_back(std::unique_ptr<HijackingInterceptorFactory>(
638 new HijackingInterceptorFactory()));
639 // Add 20 dummy interceptors after hijacking interceptor
640 for (auto i = 0; i < 20; i++) {
641 creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
642 new DummyInterceptorFactory()));
644 auto channel = experimental::CreateCustomChannelWithInterceptors(
645 server_address_, InsecureChannelCredentials(), args, std::move(creators));
648 // Make sure only 20 dummy interceptors were run
649 EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20);
652 TEST_F(ClientInterceptorsEnd2endTest, ClientInterceptorLogThenHijackTest) {
653 ChannelArguments args;
654 std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
656 creators.push_back(std::unique_ptr<LoggingInterceptorFactory>(
657 new LoggingInterceptorFactory()));
658 creators.push_back(std::unique_ptr<HijackingInterceptorFactory>(
659 new HijackingInterceptorFactory()));
660 auto channel = experimental::CreateCustomChannelWithInterceptors(
661 server_address_, InsecureChannelCredentials(), args, std::move(creators));
666 TEST_F(ClientInterceptorsEnd2endTest,
667 ClientInterceptorHijackingMakesAnotherCallTest) {
668 ChannelArguments args;
669 DummyInterceptor::Reset();
670 std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
672 // Add 5 dummy interceptors before hijacking interceptor
674 for (auto i = 0; i < 5; i++) {
675 creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
676 new DummyInterceptorFactory()));
679 std::unique_ptr<experimental::ClientInterceptorFactoryInterface>(
680 new HijackingInterceptorMakesAnotherCallFactory()));
681 // Add 7 dummy interceptors after hijacking interceptor
682 for (auto i = 0; i < 7; i++) {
683 creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
684 new DummyInterceptorFactory()));
686 auto channel = server_->experimental().InProcessChannelWithInterceptors(
687 args, std::move(creators));
690 // Make sure all interceptors were run once, since the hijacking interceptor
691 // makes an RPC on the intercepted channel
692 EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 12);
695 TEST_F(ClientInterceptorsEnd2endTest,
696 ClientInterceptorLoggingTestWithCallback) {
697 ChannelArguments args;
698 DummyInterceptor::Reset();
699 std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
701 creators.push_back(std::unique_ptr<LoggingInterceptorFactory>(
702 new LoggingInterceptorFactory()));
703 // Add 20 dummy interceptors
704 for (auto i = 0; i < 20; i++) {
705 creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
706 new DummyInterceptorFactory()));
708 auto channel = server_->experimental().InProcessChannelWithInterceptors(
709 args, std::move(creators));
710 MakeCallbackCall(channel);
711 // Make sure all 20 dummy interceptors were run
712 EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20);
715 TEST_F(ClientInterceptorsEnd2endTest,
716 ClientInterceptorFactoryAllowsNullptrReturn) {
717 ChannelArguments args;
718 DummyInterceptor::Reset();
719 std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
721 creators.push_back(std::unique_ptr<LoggingInterceptorFactory>(
722 new LoggingInterceptorFactory()));
723 // Add 20 dummy interceptors and 20 null interceptors
724 for (auto i = 0; i < 20; i++) {
725 creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
726 new DummyInterceptorFactory()));
728 std::unique_ptr<NullInterceptorFactory>(new NullInterceptorFactory()));
730 auto channel = server_->experimental().InProcessChannelWithInterceptors(
731 args, std::move(creators));
732 MakeCallbackCall(channel);
733 // Make sure all 20 dummy interceptors were run
734 EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20);
737 class ClientInterceptorsStreamingEnd2endTest : public ::testing::Test {
739 ClientInterceptorsStreamingEnd2endTest() {
740 int port = grpc_pick_unused_port_or_die();
742 ServerBuilder builder;
743 server_address_ = "localhost:" + std::to_string(port);
744 builder.AddListeningPort(server_address_, InsecureServerCredentials());
745 builder.RegisterService(&service_);
746 server_ = builder.BuildAndStart();
749 ~ClientInterceptorsStreamingEnd2endTest() { server_->Shutdown(); }
751 std::string server_address_;
752 EchoTestServiceStreamingImpl service_;
753 std::unique_ptr<Server> server_;
756 TEST_F(ClientInterceptorsStreamingEnd2endTest, ClientStreamingTest) {
757 ChannelArguments args;
758 DummyInterceptor::Reset();
759 std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
761 creators.push_back(std::unique_ptr<LoggingInterceptorFactory>(
762 new LoggingInterceptorFactory()));
763 // Add 20 dummy interceptors
764 for (auto i = 0; i < 20; i++) {
765 creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
766 new DummyInterceptorFactory()));
768 auto channel = experimental::CreateCustomChannelWithInterceptors(
769 server_address_, InsecureChannelCredentials(), args, std::move(creators));
770 MakeClientStreamingCall(channel);
771 // Make sure all 20 dummy interceptors were run
772 EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20);
775 TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingTest) {
776 ChannelArguments args;
777 DummyInterceptor::Reset();
778 std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
780 creators.push_back(std::unique_ptr<LoggingInterceptorFactory>(
781 new LoggingInterceptorFactory()));
782 // Add 20 dummy interceptors
783 for (auto i = 0; i < 20; i++) {
784 creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
785 new DummyInterceptorFactory()));
787 auto channel = experimental::CreateCustomChannelWithInterceptors(
788 server_address_, InsecureChannelCredentials(), args, std::move(creators));
789 MakeServerStreamingCall(channel);
790 // Make sure all 20 dummy interceptors were run
791 EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20);
794 TEST_F(ClientInterceptorsStreamingEnd2endTest, ClientStreamingHijackingTest) {
795 ChannelArguments args;
796 std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
799 std::unique_ptr<ClientStreamingRpcHijackingInterceptorFactory>(
800 new ClientStreamingRpcHijackingInterceptorFactory()));
801 auto channel = experimental::CreateCustomChannelWithInterceptors(
802 server_address_, InsecureChannelCredentials(), args, std::move(creators));
804 auto stub = grpc::testing::EchoTestService::NewStub(channel);
808 req.mutable_param()->set_echo_metadata(true);
809 req.set_message("Hello");
810 string expected_resp = "";
811 auto writer = stub->RequestStream(&ctx, &resp);
812 for (int i = 0; i < 10; i++) {
813 EXPECT_TRUE(writer->Write(req));
814 expected_resp += "Hello";
816 // The interceptor will reject the 11th message
818 Status s = writer->Finish();
819 EXPECT_EQ(s.ok(), false);
820 EXPECT_TRUE(ClientStreamingRpcHijackingInterceptor::GotFailedSend());
823 TEST_F(ClientInterceptorsStreamingEnd2endTest, ServerStreamingHijackingTest) {
824 ChannelArguments args;
825 DummyInterceptor::Reset();
826 std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
829 std::unique_ptr<ServerStreamingRpcHijackingInterceptorFactory>(
830 new ServerStreamingRpcHijackingInterceptorFactory()));
831 auto channel = experimental::CreateCustomChannelWithInterceptors(
832 server_address_, InsecureChannelCredentials(), args, std::move(creators));
833 MakeServerStreamingCall(channel);
834 EXPECT_TRUE(ServerStreamingRpcHijackingInterceptor::GotFailedMessage());
837 TEST_F(ClientInterceptorsStreamingEnd2endTest, BidiStreamingHijackingTest) {
838 ChannelArguments args;
839 DummyInterceptor::Reset();
840 std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
843 std::unique_ptr<BidiStreamingRpcHijackingInterceptorFactory>(
844 new BidiStreamingRpcHijackingInterceptorFactory()));
845 auto channel = experimental::CreateCustomChannelWithInterceptors(
846 server_address_, InsecureChannelCredentials(), args, std::move(creators));
847 MakeBidiStreamingCall(channel);
850 TEST_F(ClientInterceptorsStreamingEnd2endTest, BidiStreamingTest) {
851 ChannelArguments args;
852 DummyInterceptor::Reset();
853 std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
855 creators.push_back(std::unique_ptr<LoggingInterceptorFactory>(
856 new LoggingInterceptorFactory()));
857 // Add 20 dummy interceptors
858 for (auto i = 0; i < 20; i++) {
859 creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
860 new DummyInterceptorFactory()));
862 auto channel = experimental::CreateCustomChannelWithInterceptors(
863 server_address_, InsecureChannelCredentials(), args, std::move(creators));
864 MakeBidiStreamingCall(channel);
865 // Make sure all 20 dummy interceptors were run
866 EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20);
869 class ClientGlobalInterceptorEnd2endTest : public ::testing::Test {
871 ClientGlobalInterceptorEnd2endTest() {
872 int port = grpc_pick_unused_port_or_die();
874 ServerBuilder builder;
875 server_address_ = "localhost:" + std::to_string(port);
876 builder.AddListeningPort(server_address_, InsecureServerCredentials());
877 builder.RegisterService(&service_);
878 server_ = builder.BuildAndStart();
881 ~ClientGlobalInterceptorEnd2endTest() { server_->Shutdown(); }
883 std::string server_address_;
884 TestServiceImpl service_;
885 std::unique_ptr<Server> server_;
888 TEST_F(ClientGlobalInterceptorEnd2endTest, DummyGlobalInterceptor) {
889 // We should ideally be registering a global interceptor only once per
890 // process, but for the purposes of testing, it should be fine to modify the
891 // registered global interceptor when there are no ongoing gRPC operations
892 DummyInterceptorFactory global_factory;
893 experimental::RegisterGlobalClientInterceptorFactory(&global_factory);
894 ChannelArguments args;
895 DummyInterceptor::Reset();
896 std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
898 // Add 20 dummy interceptors
899 creators.reserve(20);
900 for (auto i = 0; i < 20; i++) {
901 creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
902 new DummyInterceptorFactory()));
904 auto channel = experimental::CreateCustomChannelWithInterceptors(
905 server_address_, InsecureChannelCredentials(), args, std::move(creators));
907 // Make sure all 20 dummy interceptors were run with the global interceptor
908 EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 21);
909 experimental::TestOnlyResetGlobalClientInterceptorFactory();
912 TEST_F(ClientGlobalInterceptorEnd2endTest, LoggingGlobalInterceptor) {
913 // We should ideally be registering a global interceptor only once per
914 // process, but for the purposes of testing, it should be fine to modify the
915 // registered global interceptor when there are no ongoing gRPC operations
916 LoggingInterceptorFactory global_factory;
917 experimental::RegisterGlobalClientInterceptorFactory(&global_factory);
918 ChannelArguments args;
919 DummyInterceptor::Reset();
920 std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
922 // Add 20 dummy interceptors
923 creators.reserve(20);
924 for (auto i = 0; i < 20; i++) {
925 creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
926 new DummyInterceptorFactory()));
928 auto channel = experimental::CreateCustomChannelWithInterceptors(
929 server_address_, InsecureChannelCredentials(), args, std::move(creators));
931 // Make sure all 20 dummy interceptors were run
932 EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20);
933 experimental::TestOnlyResetGlobalClientInterceptorFactory();
936 TEST_F(ClientGlobalInterceptorEnd2endTest, HijackingGlobalInterceptor) {
937 // We should ideally be registering a global interceptor only once per
938 // process, but for the purposes of testing, it should be fine to modify the
939 // registered global interceptor when there are no ongoing gRPC operations
940 HijackingInterceptorFactory global_factory;
941 experimental::RegisterGlobalClientInterceptorFactory(&global_factory);
942 ChannelArguments args;
943 DummyInterceptor::Reset();
944 std::vector<std::unique_ptr<experimental::ClientInterceptorFactoryInterface>>
946 // Add 20 dummy interceptors
947 creators.reserve(20);
948 for (auto i = 0; i < 20; i++) {
949 creators.push_back(std::unique_ptr<DummyInterceptorFactory>(
950 new DummyInterceptorFactory()));
952 auto channel = experimental::CreateCustomChannelWithInterceptors(
953 server_address_, InsecureChannelCredentials(), args, std::move(creators));
955 // Make sure all 20 dummy interceptors were run
956 EXPECT_EQ(DummyInterceptor::GetNumTimesRun(), 20);
957 experimental::TestOnlyResetGlobalClientInterceptorFactory();
961 } // namespace testing
964 int main(int argc, char** argv) {
965 grpc::testing::TestEnvironment env(argc, argv);
966 ::testing::InitGoogleTest(&argc, argv);
967 return RUN_ALL_TESTS();