xref: /aosp_15_r20/external/grpc-grpc/test/cpp/end2end/shutdown_test.cc (revision cc02d7e222339f7a4f6ba5f422e6413f4bd931f2)
1*cc02d7e2SAndroid Build Coastguard Worker //
2*cc02d7e2SAndroid Build Coastguard Worker //
3*cc02d7e2SAndroid Build Coastguard Worker // Copyright 2015 gRPC authors.
4*cc02d7e2SAndroid Build Coastguard Worker //
5*cc02d7e2SAndroid Build Coastguard Worker // Licensed under the Apache License, Version 2.0 (the "License");
6*cc02d7e2SAndroid Build Coastguard Worker // you may not use this file except in compliance with the License.
7*cc02d7e2SAndroid Build Coastguard Worker // You may obtain a copy of the License at
8*cc02d7e2SAndroid Build Coastguard Worker //
9*cc02d7e2SAndroid Build Coastguard Worker //     http://www.apache.org/licenses/LICENSE-2.0
10*cc02d7e2SAndroid Build Coastguard Worker //
11*cc02d7e2SAndroid Build Coastguard Worker // Unless required by applicable law or agreed to in writing, software
12*cc02d7e2SAndroid Build Coastguard Worker // distributed under the License is distributed on an "AS IS" BASIS,
13*cc02d7e2SAndroid Build Coastguard Worker // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14*cc02d7e2SAndroid Build Coastguard Worker // See the License for the specific language governing permissions and
15*cc02d7e2SAndroid Build Coastguard Worker // limitations under the License.
16*cc02d7e2SAndroid Build Coastguard Worker //
17*cc02d7e2SAndroid Build Coastguard Worker //
18*cc02d7e2SAndroid Build Coastguard Worker 
19*cc02d7e2SAndroid Build Coastguard Worker #include <thread>
20*cc02d7e2SAndroid Build Coastguard Worker 
21*cc02d7e2SAndroid Build Coastguard Worker #include <gtest/gtest.h>
22*cc02d7e2SAndroid Build Coastguard Worker 
23*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/grpc.h>
24*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/support/log.h>
25*cc02d7e2SAndroid Build Coastguard Worker #include <grpc/support/sync.h>
26*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/channel.h>
27*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/client_context.h>
28*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/create_channel.h>
29*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/server.h>
30*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/server_builder.h>
31*cc02d7e2SAndroid Build Coastguard Worker #include <grpcpp/server_context.h>
32*cc02d7e2SAndroid Build Coastguard Worker 
33*cc02d7e2SAndroid Build Coastguard Worker #include "src/core/lib/gprpp/crash.h"
34*cc02d7e2SAndroid Build Coastguard Worker #include "src/core/lib/gprpp/env.h"
35*cc02d7e2SAndroid Build Coastguard Worker #include "src/proto/grpc/testing/echo.grpc.pb.h"
36*cc02d7e2SAndroid Build Coastguard Worker #include "test/core/util/port.h"
37*cc02d7e2SAndroid Build Coastguard Worker #include "test/core/util/test_config.h"
38*cc02d7e2SAndroid Build Coastguard Worker #include "test/cpp/util/test_credentials_provider.h"
39*cc02d7e2SAndroid Build Coastguard Worker 
40*cc02d7e2SAndroid Build Coastguard Worker namespace grpc {
41*cc02d7e2SAndroid Build Coastguard Worker namespace testing {
42*cc02d7e2SAndroid Build Coastguard Worker 
43*cc02d7e2SAndroid Build Coastguard Worker class TestServiceImpl : public grpc::testing::EchoTestService::Service {
44*cc02d7e2SAndroid Build Coastguard Worker  public:
TestServiceImpl(gpr_event * ev)45*cc02d7e2SAndroid Build Coastguard Worker   explicit TestServiceImpl(gpr_event* ev) : ev_(ev) {}
46*cc02d7e2SAndroid Build Coastguard Worker 
Echo(ServerContext * context,const EchoRequest *,EchoResponse *)47*cc02d7e2SAndroid Build Coastguard Worker   Status Echo(ServerContext* context, const EchoRequest* /*request*/,
48*cc02d7e2SAndroid Build Coastguard Worker               EchoResponse* /*response*/) override {
49*cc02d7e2SAndroid Build Coastguard Worker     gpr_event_set(ev_, reinterpret_cast<void*>(1));
50*cc02d7e2SAndroid Build Coastguard Worker     while (!context->IsCancelled()) {
51*cc02d7e2SAndroid Build Coastguard Worker     }
52*cc02d7e2SAndroid Build Coastguard Worker     return Status::OK;
53*cc02d7e2SAndroid Build Coastguard Worker   }
54*cc02d7e2SAndroid Build Coastguard Worker 
55*cc02d7e2SAndroid Build Coastguard Worker  private:
56*cc02d7e2SAndroid Build Coastguard Worker   gpr_event* ev_;
57*cc02d7e2SAndroid Build Coastguard Worker };
58*cc02d7e2SAndroid Build Coastguard Worker 
59*cc02d7e2SAndroid Build Coastguard Worker class ShutdownTest : public ::testing::TestWithParam<string> {
60*cc02d7e2SAndroid Build Coastguard Worker  public:
ShutdownTest()61*cc02d7e2SAndroid Build Coastguard Worker   ShutdownTest() : shutdown_(false), service_(&ev_) { gpr_event_init(&ev_); }
62*cc02d7e2SAndroid Build Coastguard Worker 
SetUp()63*cc02d7e2SAndroid Build Coastguard Worker   void SetUp() override {
64*cc02d7e2SAndroid Build Coastguard Worker     port_ = grpc_pick_unused_port_or_die();
65*cc02d7e2SAndroid Build Coastguard Worker     server_ = SetUpServer(port_);
66*cc02d7e2SAndroid Build Coastguard Worker   }
67*cc02d7e2SAndroid Build Coastguard Worker 
SetUpServer(const int port)68*cc02d7e2SAndroid Build Coastguard Worker   std::unique_ptr<Server> SetUpServer(const int port) {
69*cc02d7e2SAndroid Build Coastguard Worker     std::string server_address = "localhost:" + to_string(port);
70*cc02d7e2SAndroid Build Coastguard Worker 
71*cc02d7e2SAndroid Build Coastguard Worker     ServerBuilder builder;
72*cc02d7e2SAndroid Build Coastguard Worker     auto server_creds =
73*cc02d7e2SAndroid Build Coastguard Worker         GetCredentialsProvider()->GetServerCredentials(GetParam());
74*cc02d7e2SAndroid Build Coastguard Worker     builder.AddListeningPort(server_address, server_creds);
75*cc02d7e2SAndroid Build Coastguard Worker     builder.RegisterService(&service_);
76*cc02d7e2SAndroid Build Coastguard Worker     std::unique_ptr<Server> server = builder.BuildAndStart();
77*cc02d7e2SAndroid Build Coastguard Worker     return server;
78*cc02d7e2SAndroid Build Coastguard Worker   }
79*cc02d7e2SAndroid Build Coastguard Worker 
TearDown()80*cc02d7e2SAndroid Build Coastguard Worker   void TearDown() override { GPR_ASSERT(shutdown_); }
81*cc02d7e2SAndroid Build Coastguard Worker 
ResetStub()82*cc02d7e2SAndroid Build Coastguard Worker   void ResetStub() {
83*cc02d7e2SAndroid Build Coastguard Worker     string target = "dns:localhost:" + to_string(port_);
84*cc02d7e2SAndroid Build Coastguard Worker     ChannelArguments args;
85*cc02d7e2SAndroid Build Coastguard Worker     auto channel_creds =
86*cc02d7e2SAndroid Build Coastguard Worker         GetCredentialsProvider()->GetChannelCredentials(GetParam(), &args);
87*cc02d7e2SAndroid Build Coastguard Worker     channel_ = grpc::CreateCustomChannel(target, channel_creds, args);
88*cc02d7e2SAndroid Build Coastguard Worker     stub_ = grpc::testing::EchoTestService::NewStub(channel_);
89*cc02d7e2SAndroid Build Coastguard Worker   }
90*cc02d7e2SAndroid Build Coastguard Worker 
to_string(const int number)91*cc02d7e2SAndroid Build Coastguard Worker   string to_string(const int number) {
92*cc02d7e2SAndroid Build Coastguard Worker     std::stringstream strs;
93*cc02d7e2SAndroid Build Coastguard Worker     strs << number;
94*cc02d7e2SAndroid Build Coastguard Worker     return strs.str();
95*cc02d7e2SAndroid Build Coastguard Worker   }
96*cc02d7e2SAndroid Build Coastguard Worker 
SendRequest()97*cc02d7e2SAndroid Build Coastguard Worker   void SendRequest() {
98*cc02d7e2SAndroid Build Coastguard Worker     EchoRequest request;
99*cc02d7e2SAndroid Build Coastguard Worker     EchoResponse response;
100*cc02d7e2SAndroid Build Coastguard Worker     request.set_message("Hello");
101*cc02d7e2SAndroid Build Coastguard Worker     ClientContext context;
102*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(!shutdown_);
103*cc02d7e2SAndroid Build Coastguard Worker     Status s = stub_->Echo(&context, request, &response);
104*cc02d7e2SAndroid Build Coastguard Worker     GPR_ASSERT(shutdown_);
105*cc02d7e2SAndroid Build Coastguard Worker   }
106*cc02d7e2SAndroid Build Coastguard Worker 
107*cc02d7e2SAndroid Build Coastguard Worker  protected:
108*cc02d7e2SAndroid Build Coastguard Worker   std::shared_ptr<Channel> channel_;
109*cc02d7e2SAndroid Build Coastguard Worker   std::unique_ptr<grpc::testing::EchoTestService::Stub> stub_;
110*cc02d7e2SAndroid Build Coastguard Worker   std::unique_ptr<Server> server_;
111*cc02d7e2SAndroid Build Coastguard Worker   bool shutdown_;
112*cc02d7e2SAndroid Build Coastguard Worker   int port_;
113*cc02d7e2SAndroid Build Coastguard Worker   gpr_event ev_;
114*cc02d7e2SAndroid Build Coastguard Worker   TestServiceImpl service_;
115*cc02d7e2SAndroid Build Coastguard Worker };
116*cc02d7e2SAndroid Build Coastguard Worker 
GetAllCredentialsTypeList()117*cc02d7e2SAndroid Build Coastguard Worker std::vector<string> GetAllCredentialsTypeList() {
118*cc02d7e2SAndroid Build Coastguard Worker   std::vector<std::string> credentials_types;
119*cc02d7e2SAndroid Build Coastguard Worker   if (GetCredentialsProvider()->GetChannelCredentials(kInsecureCredentialsType,
120*cc02d7e2SAndroid Build Coastguard Worker                                                       nullptr) != nullptr) {
121*cc02d7e2SAndroid Build Coastguard Worker     credentials_types.push_back(kInsecureCredentialsType);
122*cc02d7e2SAndroid Build Coastguard Worker   }
123*cc02d7e2SAndroid Build Coastguard Worker   auto sec_list = GetCredentialsProvider()->GetSecureCredentialsTypeList();
124*cc02d7e2SAndroid Build Coastguard Worker   for (auto sec = sec_list.begin(); sec != sec_list.end(); sec++) {
125*cc02d7e2SAndroid Build Coastguard Worker     credentials_types.push_back(*sec);
126*cc02d7e2SAndroid Build Coastguard Worker   }
127*cc02d7e2SAndroid Build Coastguard Worker   GPR_ASSERT(!credentials_types.empty());
128*cc02d7e2SAndroid Build Coastguard Worker 
129*cc02d7e2SAndroid Build Coastguard Worker   std::string credentials_type_list("credentials types:");
130*cc02d7e2SAndroid Build Coastguard Worker   for (const string& type : credentials_types) {
131*cc02d7e2SAndroid Build Coastguard Worker     credentials_type_list.append(" " + type);
132*cc02d7e2SAndroid Build Coastguard Worker   }
133*cc02d7e2SAndroid Build Coastguard Worker   gpr_log(GPR_INFO, "%s", credentials_type_list.c_str());
134*cc02d7e2SAndroid Build Coastguard Worker   return credentials_types;
135*cc02d7e2SAndroid Build Coastguard Worker }
136*cc02d7e2SAndroid Build Coastguard Worker 
137*cc02d7e2SAndroid Build Coastguard Worker INSTANTIATE_TEST_SUITE_P(End2EndShutdown, ShutdownTest,
138*cc02d7e2SAndroid Build Coastguard Worker                          ::testing::ValuesIn(GetAllCredentialsTypeList()));
139*cc02d7e2SAndroid Build Coastguard Worker 
140*cc02d7e2SAndroid Build Coastguard Worker // TODO(ctiller): leaked objects in this test
TEST_P(ShutdownTest,ShutdownTest)141*cc02d7e2SAndroid Build Coastguard Worker TEST_P(ShutdownTest, ShutdownTest) {
142*cc02d7e2SAndroid Build Coastguard Worker   ResetStub();
143*cc02d7e2SAndroid Build Coastguard Worker 
144*cc02d7e2SAndroid Build Coastguard Worker   // send the request in a background thread
145*cc02d7e2SAndroid Build Coastguard Worker   std::thread thr(std::bind(&ShutdownTest::SendRequest, this));
146*cc02d7e2SAndroid Build Coastguard Worker 
147*cc02d7e2SAndroid Build Coastguard Worker   // wait for the server to get the event
148*cc02d7e2SAndroid Build Coastguard Worker   gpr_event_wait(&ev_, gpr_inf_future(GPR_CLOCK_MONOTONIC));
149*cc02d7e2SAndroid Build Coastguard Worker 
150*cc02d7e2SAndroid Build Coastguard Worker   shutdown_ = true;
151*cc02d7e2SAndroid Build Coastguard Worker 
152*cc02d7e2SAndroid Build Coastguard Worker   // shutdown should trigger cancellation causing everything to shutdown
153*cc02d7e2SAndroid Build Coastguard Worker   auto deadline =
154*cc02d7e2SAndroid Build Coastguard Worker       std::chrono::system_clock::now() + std::chrono::microseconds(100);
155*cc02d7e2SAndroid Build Coastguard Worker   server_->Shutdown(deadline);
156*cc02d7e2SAndroid Build Coastguard Worker   EXPECT_GE(std::chrono::system_clock::now(), deadline);
157*cc02d7e2SAndroid Build Coastguard Worker 
158*cc02d7e2SAndroid Build Coastguard Worker   thr.join();
159*cc02d7e2SAndroid Build Coastguard Worker }
160*cc02d7e2SAndroid Build Coastguard Worker 
161*cc02d7e2SAndroid Build Coastguard Worker }  // namespace testing
162*cc02d7e2SAndroid Build Coastguard Worker }  // namespace grpc
163*cc02d7e2SAndroid Build Coastguard Worker 
main(int argc,char ** argv)164*cc02d7e2SAndroid Build Coastguard Worker int main(int argc, char** argv) {
165*cc02d7e2SAndroid Build Coastguard Worker   grpc::testing::TestEnvironment env(&argc, argv);
166*cc02d7e2SAndroid Build Coastguard Worker   ::testing::InitGoogleTest(&argc, argv);
167*cc02d7e2SAndroid Build Coastguard Worker   return RUN_ALL_TESTS();
168*cc02d7e2SAndroid Build Coastguard Worker }
169