Imported Upstream version 1.41.0
[platform/upstream/grpc.git] / test / cpp / end2end / health_service_end2end_test.cc
1 /*
2  *
3  * Copyright 2016 gRPC authors.
4  *
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
8  *
9  *     http://www.apache.org/licenses/LICENSE-2.0
10  *
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.
16  *
17  */
18
19 #include <memory>
20 #include <mutex>
21 #include <thread>
22 #include <vector>
23
24 #include <gtest/gtest.h>
25
26 #include <grpc/grpc.h>
27 #include <grpc/support/log.h>
28 #include <grpcpp/channel.h>
29 #include <grpcpp/client_context.h>
30 #include <grpcpp/create_channel.h>
31 #include <grpcpp/ext/health_check_service_server_builder_option.h>
32 #include <grpcpp/health_check_service_interface.h>
33 #include <grpcpp/server.h>
34 #include <grpcpp/server_builder.h>
35 #include <grpcpp/server_context.h>
36
37 #include "src/proto/grpc/health/v1/health.grpc.pb.h"
38 #include "src/proto/grpc/testing/duplicate/echo_duplicate.grpc.pb.h"
39 #include "src/proto/grpc/testing/echo.grpc.pb.h"
40 #include "test/core/util/port.h"
41 #include "test/core/util/test_config.h"
42 #include "test/cpp/end2end/test_health_check_service_impl.h"
43 #include "test/cpp/end2end/test_service_impl.h"
44
45 using grpc::health::v1::Health;
46 using grpc::health::v1::HealthCheckRequest;
47 using grpc::health::v1::HealthCheckResponse;
48
49 namespace grpc {
50 namespace testing {
51 namespace {
52
53 // A custom implementation of the health checking service interface. This is
54 // used to test that it prevents the server from creating a default service and
55 // also serves as an example of how to override the default service.
56 class CustomHealthCheckService : public HealthCheckServiceInterface {
57  public:
58   explicit CustomHealthCheckService(HealthCheckServiceImpl* impl)
59       : impl_(impl) {
60     impl_->SetStatus("", HealthCheckResponse::SERVING);
61   }
62   void SetServingStatus(const std::string& service_name,
63                         bool serving) override {
64     impl_->SetStatus(service_name, serving ? HealthCheckResponse::SERVING
65                                            : HealthCheckResponse::NOT_SERVING);
66   }
67
68   void SetServingStatus(bool serving) override {
69     impl_->SetAll(serving ? HealthCheckResponse::SERVING
70                           : HealthCheckResponse::NOT_SERVING);
71   }
72
73   void Shutdown() override { impl_->Shutdown(); }
74
75  private:
76   HealthCheckServiceImpl* impl_;  // not owned
77 };
78
79 class HealthServiceEnd2endTest : public ::testing::Test {
80  protected:
81   HealthServiceEnd2endTest() {}
82
83   void SetUpServer(bool register_sync_test_service, bool add_async_cq,
84                    bool explicit_health_service,
85                    std::unique_ptr<HealthCheckServiceInterface> service) {
86     int port = grpc_pick_unused_port_or_die();
87     server_address_ << "localhost:" << port;
88
89     bool register_sync_health_service_impl =
90         explicit_health_service && service != nullptr;
91
92     // Setup server
93     ServerBuilder builder;
94     if (explicit_health_service) {
95       std::unique_ptr<ServerBuilderOption> option(
96           new HealthCheckServiceServerBuilderOption(std::move(service)));
97       builder.SetOption(std::move(option));
98     }
99     builder.AddListeningPort(server_address_.str(),
100                              grpc::InsecureServerCredentials());
101     if (register_sync_test_service) {
102       // Register a sync service.
103       builder.RegisterService(&echo_test_service_);
104     }
105     if (register_sync_health_service_impl) {
106       builder.RegisterService(&health_check_service_impl_);
107     }
108     if (add_async_cq) {
109       cq_ = builder.AddCompletionQueue();
110     }
111     server_ = builder.BuildAndStart();
112   }
113
114   void TearDown() override {
115     if (server_) {
116       server_->Shutdown();
117       if (cq_ != nullptr) {
118         cq_->Shutdown();
119       }
120       if (cq_thread_.joinable()) {
121         cq_thread_.join();
122       }
123     }
124   }
125
126   void ResetStubs() {
127     std::shared_ptr<Channel> channel = grpc::CreateChannel(
128         server_address_.str(), InsecureChannelCredentials());
129     hc_stub_ = grpc::health::v1::Health::NewStub(channel);
130   }
131
132   // When the expected_status is NOT OK, we do not care about the response.
133   void SendHealthCheckRpc(const std::string& service_name,
134                           const Status& expected_status) {
135     EXPECT_FALSE(expected_status.ok());
136     SendHealthCheckRpc(service_name, expected_status,
137                        HealthCheckResponse::UNKNOWN);
138   }
139
140   void SendHealthCheckRpc(
141       const std::string& service_name, const Status& expected_status,
142       HealthCheckResponse::ServingStatus expected_serving_status) {
143     HealthCheckRequest request;
144     request.set_service(service_name);
145     HealthCheckResponse response;
146     ClientContext context;
147     Status s = hc_stub_->Check(&context, request, &response);
148     EXPECT_EQ(expected_status.error_code(), s.error_code());
149     if (s.ok()) {
150       EXPECT_EQ(expected_serving_status, response.status());
151     }
152   }
153
154   void VerifyHealthCheckService() {
155     HealthCheckServiceInterface* service = server_->GetHealthCheckService();
156     EXPECT_TRUE(service != nullptr);
157     const std::string kHealthyService("healthy_service");
158     const std::string kUnhealthyService("unhealthy_service");
159     const std::string kNotRegisteredService("not_registered");
160     service->SetServingStatus(kHealthyService, true);
161     service->SetServingStatus(kUnhealthyService, false);
162
163     ResetStubs();
164
165     SendHealthCheckRpc("", Status::OK, HealthCheckResponse::SERVING);
166     SendHealthCheckRpc(kHealthyService, Status::OK,
167                        HealthCheckResponse::SERVING);
168     SendHealthCheckRpc(kUnhealthyService, Status::OK,
169                        HealthCheckResponse::NOT_SERVING);
170     SendHealthCheckRpc(kNotRegisteredService,
171                        Status(StatusCode::NOT_FOUND, ""));
172
173     service->SetServingStatus(false);
174     SendHealthCheckRpc("", Status::OK, HealthCheckResponse::NOT_SERVING);
175     SendHealthCheckRpc(kHealthyService, Status::OK,
176                        HealthCheckResponse::NOT_SERVING);
177     SendHealthCheckRpc(kUnhealthyService, Status::OK,
178                        HealthCheckResponse::NOT_SERVING);
179     SendHealthCheckRpc(kNotRegisteredService,
180                        Status(StatusCode::NOT_FOUND, ""));
181   }
182
183   void VerifyHealthCheckServiceStreaming() {
184     const std::string kServiceName("service_name");
185     HealthCheckServiceInterface* service = server_->GetHealthCheckService();
186     // Start Watch for service.
187     ClientContext context;
188     HealthCheckRequest request;
189     request.set_service(kServiceName);
190     std::unique_ptr<::grpc::ClientReaderInterface<HealthCheckResponse>> reader =
191         hc_stub_->Watch(&context, request);
192     // Initial response will be SERVICE_UNKNOWN.
193     HealthCheckResponse response;
194     EXPECT_TRUE(reader->Read(&response));
195     EXPECT_EQ(response.SERVICE_UNKNOWN, response.status());
196     response.Clear();
197     // Now set service to NOT_SERVING and make sure we get an update.
198     service->SetServingStatus(kServiceName, false);
199     EXPECT_TRUE(reader->Read(&response));
200     EXPECT_EQ(response.NOT_SERVING, response.status());
201     response.Clear();
202     // Now set service to SERVING and make sure we get another update.
203     service->SetServingStatus(kServiceName, true);
204     EXPECT_TRUE(reader->Read(&response));
205     EXPECT_EQ(response.SERVING, response.status());
206     // Finish call.
207     context.TryCancel();
208   }
209
210   // Verify that after HealthCheckServiceInterface::Shutdown is called
211   // 1. unary client will see NOT_SERVING.
212   // 2. unary client still sees NOT_SERVING after a SetServing(true) is called.
213   // 3. streaming (Watch) client will see an update.
214   // 4. setting a new service to serving after shutdown will add the service
215   // name but return NOT_SERVING to client.
216   // This has to be called last.
217   void VerifyHealthCheckServiceShutdown() {
218     HealthCheckServiceInterface* service = server_->GetHealthCheckService();
219     EXPECT_TRUE(service != nullptr);
220     const std::string kHealthyService("healthy_service");
221     const std::string kUnhealthyService("unhealthy_service");
222     const std::string kNotRegisteredService("not_registered");
223     const std::string kNewService("add_after_shutdown");
224     service->SetServingStatus(kHealthyService, true);
225     service->SetServingStatus(kUnhealthyService, false);
226
227     ResetStubs();
228
229     // Start Watch for service.
230     ClientContext context;
231     HealthCheckRequest request;
232     request.set_service(kHealthyService);
233     std::unique_ptr<::grpc::ClientReaderInterface<HealthCheckResponse>> reader =
234         hc_stub_->Watch(&context, request);
235
236     HealthCheckResponse response;
237     EXPECT_TRUE(reader->Read(&response));
238     EXPECT_EQ(response.SERVING, response.status());
239
240     SendHealthCheckRpc("", Status::OK, HealthCheckResponse::SERVING);
241     SendHealthCheckRpc(kHealthyService, Status::OK,
242                        HealthCheckResponse::SERVING);
243     SendHealthCheckRpc(kUnhealthyService, Status::OK,
244                        HealthCheckResponse::NOT_SERVING);
245     SendHealthCheckRpc(kNotRegisteredService,
246                        Status(StatusCode::NOT_FOUND, ""));
247     SendHealthCheckRpc(kNewService, Status(StatusCode::NOT_FOUND, ""));
248
249     // Shutdown health check service.
250     service->Shutdown();
251
252     // Watch client gets another update.
253     EXPECT_TRUE(reader->Read(&response));
254     EXPECT_EQ(response.NOT_SERVING, response.status());
255     // Finish Watch call.
256     context.TryCancel();
257
258     SendHealthCheckRpc("", Status::OK, HealthCheckResponse::NOT_SERVING);
259     SendHealthCheckRpc(kHealthyService, Status::OK,
260                        HealthCheckResponse::NOT_SERVING);
261     SendHealthCheckRpc(kUnhealthyService, Status::OK,
262                        HealthCheckResponse::NOT_SERVING);
263     SendHealthCheckRpc(kNotRegisteredService,
264                        Status(StatusCode::NOT_FOUND, ""));
265
266     // Setting status after Shutdown has no effect.
267     service->SetServingStatus(kHealthyService, true);
268     SendHealthCheckRpc(kHealthyService, Status::OK,
269                        HealthCheckResponse::NOT_SERVING);
270
271     // Adding serving status for a new service after shutdown will return
272     // NOT_SERVING.
273     service->SetServingStatus(kNewService, true);
274     SendHealthCheckRpc(kNewService, Status::OK,
275                        HealthCheckResponse::NOT_SERVING);
276   }
277
278   TestServiceImpl echo_test_service_;
279   HealthCheckServiceImpl health_check_service_impl_;
280   std::unique_ptr<Health::Stub> hc_stub_;
281   std::unique_ptr<ServerCompletionQueue> cq_;
282   std::unique_ptr<Server> server_;
283   std::ostringstream server_address_;
284   std::thread cq_thread_;
285 };
286
287 TEST_F(HealthServiceEnd2endTest, DefaultHealthServiceDisabled) {
288   EnableDefaultHealthCheckService(false);
289   EXPECT_FALSE(DefaultHealthCheckServiceEnabled());
290   SetUpServer(true, false, false, nullptr);
291   HealthCheckServiceInterface* default_service =
292       server_->GetHealthCheckService();
293   EXPECT_TRUE(default_service == nullptr);
294
295   ResetStubs();
296
297   SendHealthCheckRpc("", Status(StatusCode::UNIMPLEMENTED, ""));
298 }
299
300 TEST_F(HealthServiceEnd2endTest, DefaultHealthService) {
301   EnableDefaultHealthCheckService(true);
302   EXPECT_TRUE(DefaultHealthCheckServiceEnabled());
303   SetUpServer(true, false, false, nullptr);
304   VerifyHealthCheckService();
305   VerifyHealthCheckServiceStreaming();
306
307   // The default service has a size limit of the service name.
308   const std::string kTooLongServiceName(201, 'x');
309   SendHealthCheckRpc(kTooLongServiceName,
310                      Status(StatusCode::INVALID_ARGUMENT, ""));
311 }
312
313 TEST_F(HealthServiceEnd2endTest, DefaultHealthServiceShutdown) {
314   EnableDefaultHealthCheckService(true);
315   EXPECT_TRUE(DefaultHealthCheckServiceEnabled());
316   SetUpServer(true, false, false, nullptr);
317   VerifyHealthCheckServiceShutdown();
318 }
319
320 // Provide an empty service to disable the default service.
321 TEST_F(HealthServiceEnd2endTest, ExplicitlyDisableViaOverride) {
322   EnableDefaultHealthCheckService(true);
323   EXPECT_TRUE(DefaultHealthCheckServiceEnabled());
324   std::unique_ptr<HealthCheckServiceInterface> empty_service;
325   SetUpServer(true, false, true, std::move(empty_service));
326   HealthCheckServiceInterface* service = server_->GetHealthCheckService();
327   EXPECT_TRUE(service == nullptr);
328
329   ResetStubs();
330
331   SendHealthCheckRpc("", Status(StatusCode::UNIMPLEMENTED, ""));
332 }
333
334 // Provide an explicit override of health checking service interface.
335 TEST_F(HealthServiceEnd2endTest, ExplicitlyOverride) {
336   EnableDefaultHealthCheckService(true);
337   EXPECT_TRUE(DefaultHealthCheckServiceEnabled());
338   std::unique_ptr<HealthCheckServiceInterface> override_service(
339       new CustomHealthCheckService(&health_check_service_impl_));
340   HealthCheckServiceInterface* underlying_service = override_service.get();
341   SetUpServer(false, false, true, std::move(override_service));
342   HealthCheckServiceInterface* service = server_->GetHealthCheckService();
343   EXPECT_TRUE(service == underlying_service);
344
345   ResetStubs();
346
347   VerifyHealthCheckService();
348   VerifyHealthCheckServiceStreaming();
349 }
350
351 TEST_F(HealthServiceEnd2endTest, ExplicitlyHealthServiceShutdown) {
352   EnableDefaultHealthCheckService(true);
353   EXPECT_TRUE(DefaultHealthCheckServiceEnabled());
354   std::unique_ptr<HealthCheckServiceInterface> override_service(
355       new CustomHealthCheckService(&health_check_service_impl_));
356   HealthCheckServiceInterface* underlying_service = override_service.get();
357   SetUpServer(false, false, true, std::move(override_service));
358   HealthCheckServiceInterface* service = server_->GetHealthCheckService();
359   EXPECT_TRUE(service == underlying_service);
360
361   ResetStubs();
362
363   VerifyHealthCheckServiceShutdown();
364 }
365
366 }  // namespace
367 }  // namespace testing
368 }  // namespace grpc
369
370 int main(int argc, char** argv) {
371   grpc::testing::TestEnvironment env(argc, argv);
372   ::testing::InitGoogleTest(&argc, argv);
373   return RUN_ALL_TESTS();
374 }