3 * Copyright 2016 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.
24 #include <gtest/gtest.h>
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>
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"
45 using grpc::health::v1::Health;
46 using grpc::health::v1::HealthCheckRequest;
47 using grpc::health::v1::HealthCheckResponse;
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 {
58 explicit CustomHealthCheckService(HealthCheckServiceImpl* impl)
60 impl_->SetStatus("", HealthCheckResponse::SERVING);
62 void SetServingStatus(const std::string& service_name,
63 bool serving) override {
64 impl_->SetStatus(service_name, serving ? HealthCheckResponse::SERVING
65 : HealthCheckResponse::NOT_SERVING);
68 void SetServingStatus(bool serving) override {
69 impl_->SetAll(serving ? HealthCheckResponse::SERVING
70 : HealthCheckResponse::NOT_SERVING);
73 void Shutdown() override { impl_->Shutdown(); }
76 HealthCheckServiceImpl* impl_; // not owned
79 class HealthServiceEnd2endTest : public ::testing::Test {
81 HealthServiceEnd2endTest() {}
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;
89 bool register_sync_health_service_impl =
90 explicit_health_service && service != nullptr;
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));
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_);
105 if (register_sync_health_service_impl) {
106 builder.RegisterService(&health_check_service_impl_);
109 cq_ = builder.AddCompletionQueue();
111 server_ = builder.BuildAndStart();
114 void TearDown() override {
117 if (cq_ != nullptr) {
120 if (cq_thread_.joinable()) {
127 std::shared_ptr<Channel> channel = grpc::CreateChannel(
128 server_address_.str(), InsecureChannelCredentials());
129 hc_stub_ = grpc::health::v1::Health::NewStub(channel);
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);
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());
150 EXPECT_EQ(expected_serving_status, response.status());
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);
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, ""));
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, ""));
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());
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());
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());
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);
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);
236 HealthCheckResponse response;
237 EXPECT_TRUE(reader->Read(&response));
238 EXPECT_EQ(response.SERVING, response.status());
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, ""));
249 // Shutdown health check service.
252 // Watch client gets another update.
253 EXPECT_TRUE(reader->Read(&response));
254 EXPECT_EQ(response.NOT_SERVING, response.status());
255 // Finish Watch call.
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, ""));
266 // Setting status after Shutdown has no effect.
267 service->SetServingStatus(kHealthyService, true);
268 SendHealthCheckRpc(kHealthyService, Status::OK,
269 HealthCheckResponse::NOT_SERVING);
271 // Adding serving status for a new service after shutdown will return
273 service->SetServingStatus(kNewService, true);
274 SendHealthCheckRpc(kNewService, Status::OK,
275 HealthCheckResponse::NOT_SERVING);
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_;
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);
297 SendHealthCheckRpc("", Status(StatusCode::UNIMPLEMENTED, ""));
300 TEST_F(HealthServiceEnd2endTest, DefaultHealthService) {
301 EnableDefaultHealthCheckService(true);
302 EXPECT_TRUE(DefaultHealthCheckServiceEnabled());
303 SetUpServer(true, false, false, nullptr);
304 VerifyHealthCheckService();
305 VerifyHealthCheckServiceStreaming();
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, ""));
313 TEST_F(HealthServiceEnd2endTest, DefaultHealthServiceShutdown) {
314 EnableDefaultHealthCheckService(true);
315 EXPECT_TRUE(DefaultHealthCheckServiceEnabled());
316 SetUpServer(true, false, false, nullptr);
317 VerifyHealthCheckServiceShutdown();
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);
331 SendHealthCheckRpc("", Status(StatusCode::UNIMPLEMENTED, ""));
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);
347 VerifyHealthCheckService();
348 VerifyHealthCheckServiceStreaming();
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);
363 VerifyHealthCheckServiceShutdown();
367 } // namespace testing
370 int main(int argc, char** argv) {
371 grpc::testing::TestEnvironment env(argc, argv);
372 ::testing::InitGoogleTest(&argc, argv);
373 return RUN_ALL_TESTS();