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