health_service_end2end_test.cc 14 KB

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