keepalive_timeout.cc 15 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443
  1. /*
  2. *
  3. * Copyright 2017 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 <stdio.h>
  19. #include <string.h>
  20. #include <grpc/byte_buffer.h>
  21. #include <grpc/support/alloc.h>
  22. #include <grpc/support/log.h>
  23. #include <grpc/support/time.h>
  24. #include "src/core/ext/transport/chttp2/transport/frame_ping.h"
  25. #include "src/core/lib/channel/channel_args.h"
  26. #include "src/core/lib/gpr/useful.h"
  27. #include "src/core/lib/iomgr/exec_ctx.h"
  28. #include "src/core/lib/iomgr/iomgr.h"
  29. #include "test/core/end2end/cq_verifier.h"
  30. #include "test/core/end2end/end2end_tests.h"
  31. #ifdef GRPC_POSIX_SOCKET
  32. #include "src/core/lib/iomgr/ev_posix.h"
  33. #endif // GRPC_POSIX_SOCKET
  34. static void* tag(intptr_t t) { return reinterpret_cast<void*>(t); }
  35. static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
  36. const char* test_name,
  37. grpc_channel_args* client_args,
  38. grpc_channel_args* server_args) {
  39. grpc_end2end_test_fixture f;
  40. gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
  41. f = config.create_fixture(client_args, server_args);
  42. config.init_server(&f, server_args);
  43. config.init_client(&f, client_args);
  44. return f;
  45. }
  46. static gpr_timespec n_seconds_from_now(int n) {
  47. return grpc_timeout_seconds_to_deadline(n);
  48. }
  49. static gpr_timespec five_seconds_from_now(void) {
  50. return n_seconds_from_now(5);
  51. }
  52. static void drain_cq(grpc_completion_queue* cq) {
  53. grpc_event ev;
  54. do {
  55. ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
  56. } while (ev.type != GRPC_QUEUE_SHUTDOWN);
  57. }
  58. static void shutdown_server(grpc_end2end_test_fixture* f) {
  59. if (!f->server) return;
  60. grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
  61. GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
  62. five_seconds_from_now(), nullptr)
  63. .type == GRPC_OP_COMPLETE);
  64. grpc_server_destroy(f->server);
  65. f->server = nullptr;
  66. }
  67. static void shutdown_client(grpc_end2end_test_fixture* f) {
  68. if (!f->client) return;
  69. grpc_channel_destroy(f->client);
  70. f->client = nullptr;
  71. }
  72. static void end_test(grpc_end2end_test_fixture* f) {
  73. shutdown_server(f);
  74. shutdown_client(f);
  75. grpc_completion_queue_shutdown(f->cq);
  76. drain_cq(f->cq);
  77. grpc_completion_queue_destroy(f->cq);
  78. grpc_completion_queue_destroy(f->shutdown_cq);
  79. }
  80. /* Client sends a request, server replies with a payload, then waits for the
  81. keepalive watchdog timeouts before returning status. */
  82. static void test_keepalive_timeout(grpc_end2end_test_config config) {
  83. grpc_call* c;
  84. grpc_call* s;
  85. grpc_slice response_payload_slice =
  86. grpc_slice_from_copied_string("hello world");
  87. grpc_byte_buffer* response_payload =
  88. grpc_raw_byte_buffer_create(&response_payload_slice, 1);
  89. grpc_arg keepalive_arg_elems[3];
  90. keepalive_arg_elems[0].type = GRPC_ARG_INTEGER;
  91. keepalive_arg_elems[0].key = const_cast<char*>(GRPC_ARG_KEEPALIVE_TIME_MS);
  92. keepalive_arg_elems[0].value.integer = 3500;
  93. keepalive_arg_elems[1].type = GRPC_ARG_INTEGER;
  94. keepalive_arg_elems[1].key = const_cast<char*>(GRPC_ARG_KEEPALIVE_TIMEOUT_MS);
  95. keepalive_arg_elems[1].value.integer = 0;
  96. keepalive_arg_elems[2].type = GRPC_ARG_INTEGER;
  97. keepalive_arg_elems[2].key = const_cast<char*>(GRPC_ARG_HTTP2_BDP_PROBE);
  98. keepalive_arg_elems[2].value.integer = 0;
  99. grpc_channel_args keepalive_args = {GPR_ARRAY_SIZE(keepalive_arg_elems),
  100. keepalive_arg_elems};
  101. grpc_end2end_test_fixture f =
  102. begin_test(config, "keepalive_timeout", &keepalive_args, nullptr);
  103. cq_verifier* cqv = cq_verifier_create(f.cq);
  104. grpc_op ops[6];
  105. grpc_op* op;
  106. grpc_metadata_array initial_metadata_recv;
  107. grpc_metadata_array trailing_metadata_recv;
  108. grpc_metadata_array request_metadata_recv;
  109. grpc_byte_buffer* response_payload_recv = nullptr;
  110. grpc_call_details call_details;
  111. grpc_status_code status;
  112. grpc_call_error error;
  113. grpc_slice details;
  114. /* Disable ping ack to trigger the keepalive timeout */
  115. grpc_set_disable_ping_ack(true);
  116. gpr_timespec deadline = five_seconds_from_now();
  117. c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
  118. grpc_slice_from_static_string("/foo"), nullptr,
  119. deadline, nullptr);
  120. GPR_ASSERT(c);
  121. grpc_metadata_array_init(&initial_metadata_recv);
  122. grpc_metadata_array_init(&trailing_metadata_recv);
  123. grpc_metadata_array_init(&request_metadata_recv);
  124. grpc_call_details_init(&call_details);
  125. memset(ops, 0, sizeof(ops));
  126. op = ops;
  127. op->op = GRPC_OP_SEND_INITIAL_METADATA;
  128. op->data.send_initial_metadata.count = 0;
  129. op++;
  130. op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
  131. op++;
  132. op->op = GRPC_OP_RECV_INITIAL_METADATA;
  133. op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
  134. op++;
  135. op->op = GRPC_OP_RECV_MESSAGE;
  136. op->data.recv_message.recv_message = &response_payload_recv;
  137. op++;
  138. error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
  139. nullptr);
  140. GPR_ASSERT(GRPC_CALL_OK == error);
  141. GPR_ASSERT(GRPC_CALL_OK == grpc_server_request_call(
  142. f.server, &s, &call_details,
  143. &request_metadata_recv, f.cq, f.cq, tag(101)));
  144. CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
  145. cq_verify(cqv);
  146. memset(ops, 0, sizeof(ops));
  147. op = ops;
  148. op->op = GRPC_OP_SEND_INITIAL_METADATA;
  149. op->data.send_initial_metadata.count = 0;
  150. op++;
  151. op->op = GRPC_OP_SEND_MESSAGE;
  152. op->data.send_message.send_message = response_payload;
  153. op++;
  154. error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102),
  155. nullptr);
  156. GPR_ASSERT(GRPC_CALL_OK == error);
  157. CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
  158. CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
  159. cq_verify(cqv);
  160. memset(ops, 0, sizeof(ops));
  161. op = ops;
  162. op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
  163. op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
  164. op->data.recv_status_on_client.status = &status;
  165. op->data.recv_status_on_client.status_details = &details;
  166. op++;
  167. error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(3),
  168. nullptr);
  169. GPR_ASSERT(GRPC_CALL_OK == error);
  170. CQ_EXPECT_COMPLETION(cqv, tag(3), 1);
  171. cq_verify(cqv);
  172. char* details_str = grpc_slice_to_c_string(details);
  173. char* method_str = grpc_slice_to_c_string(call_details.method);
  174. GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE);
  175. GPR_ASSERT(0 == grpc_slice_str_cmp(details, "keepalive watchdog timeout"));
  176. GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo"));
  177. gpr_free(details_str);
  178. gpr_free(method_str);
  179. grpc_slice_unref(details);
  180. grpc_metadata_array_destroy(&initial_metadata_recv);
  181. grpc_metadata_array_destroy(&trailing_metadata_recv);
  182. grpc_metadata_array_destroy(&request_metadata_recv);
  183. grpc_call_details_destroy(&call_details);
  184. grpc_call_unref(c);
  185. grpc_call_unref(s);
  186. cq_verifier_destroy(cqv);
  187. grpc_byte_buffer_destroy(response_payload);
  188. grpc_byte_buffer_destroy(response_payload_recv);
  189. end_test(&f);
  190. config.tear_down_data(&f);
  191. }
  192. /* Verify that reads reset the keepalive ping timer. The client sends 30 pings
  193. * with a sleep of 10ms in between. It has a configured keepalive timer of
  194. * 200ms. In the success case, each ping ack should reset the keepalive timer so
  195. * that the keepalive ping is never sent. */
  196. static void test_read_delays_keepalive(grpc_end2end_test_config config) {
  197. #ifdef GRPC_POSIX_SOCKET
  198. grpc_core::UniquePtr<char> poller = GPR_GLOBAL_CONFIG_GET(grpc_poll_strategy);
  199. /* It is hard to get the timing right for the polling engine poll. */
  200. if ((0 == strcmp(poller.get(), "poll"))) {
  201. return;
  202. }
  203. #endif // GRPC_POSIX_SOCKET
  204. const int kPingIntervalMS = 100;
  205. grpc_arg keepalive_arg_elems[3];
  206. keepalive_arg_elems[0].type = GRPC_ARG_INTEGER;
  207. keepalive_arg_elems[0].key = const_cast<char*>(GRPC_ARG_KEEPALIVE_TIME_MS);
  208. keepalive_arg_elems[0].value.integer = 20 * kPingIntervalMS;
  209. keepalive_arg_elems[1].type = GRPC_ARG_INTEGER;
  210. keepalive_arg_elems[1].key = const_cast<char*>(GRPC_ARG_KEEPALIVE_TIMEOUT_MS);
  211. keepalive_arg_elems[1].value.integer = 0;
  212. keepalive_arg_elems[2].type = GRPC_ARG_INTEGER;
  213. keepalive_arg_elems[2].key = const_cast<char*>(GRPC_ARG_HTTP2_BDP_PROBE);
  214. keepalive_arg_elems[2].value.integer = 0;
  215. grpc_channel_args keepalive_args = {GPR_ARRAY_SIZE(keepalive_arg_elems),
  216. keepalive_arg_elems};
  217. grpc_end2end_test_fixture f = begin_test(config, "test_read_delays_keepalive",
  218. &keepalive_args, nullptr);
  219. /* Disable ping ack to trigger the keepalive timeout */
  220. grpc_set_disable_ping_ack(true);
  221. grpc_call* c;
  222. grpc_call* s;
  223. cq_verifier* cqv = cq_verifier_create(f.cq);
  224. grpc_op ops[6];
  225. grpc_op* op;
  226. grpc_metadata_array initial_metadata_recv;
  227. grpc_metadata_array trailing_metadata_recv;
  228. grpc_metadata_array request_metadata_recv;
  229. grpc_call_details call_details;
  230. grpc_status_code status;
  231. grpc_call_error error;
  232. grpc_slice details;
  233. int was_cancelled = 2;
  234. grpc_byte_buffer* request_payload;
  235. grpc_byte_buffer* request_payload_recv;
  236. grpc_byte_buffer* response_payload;
  237. grpc_byte_buffer* response_payload_recv;
  238. int i;
  239. grpc_slice request_payload_slice =
  240. grpc_slice_from_copied_string("hello world");
  241. grpc_slice response_payload_slice =
  242. grpc_slice_from_copied_string("hello you");
  243. gpr_timespec deadline = five_seconds_from_now();
  244. c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
  245. grpc_slice_from_static_string("/foo"), nullptr,
  246. deadline, nullptr);
  247. GPR_ASSERT(c);
  248. grpc_metadata_array_init(&initial_metadata_recv);
  249. grpc_metadata_array_init(&trailing_metadata_recv);
  250. grpc_metadata_array_init(&request_metadata_recv);
  251. grpc_call_details_init(&call_details);
  252. memset(ops, 0, sizeof(ops));
  253. op = ops;
  254. op->op = GRPC_OP_SEND_INITIAL_METADATA;
  255. op->data.send_initial_metadata.count = 0;
  256. op->flags = 0;
  257. op->reserved = nullptr;
  258. op++;
  259. op->op = GRPC_OP_RECV_INITIAL_METADATA;
  260. op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
  261. op->flags = 0;
  262. op->reserved = nullptr;
  263. op++;
  264. op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
  265. op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
  266. op->data.recv_status_on_client.status = &status;
  267. op->data.recv_status_on_client.status_details = &details;
  268. op->flags = 0;
  269. op->reserved = nullptr;
  270. op++;
  271. error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1),
  272. nullptr);
  273. GPR_ASSERT(GRPC_CALL_OK == error);
  274. error =
  275. grpc_server_request_call(f.server, &s, &call_details,
  276. &request_metadata_recv, f.cq, f.cq, tag(100));
  277. GPR_ASSERT(GRPC_CALL_OK == error);
  278. CQ_EXPECT_COMPLETION(cqv, tag(100), 1);
  279. cq_verify(cqv);
  280. memset(ops, 0, sizeof(ops));
  281. op = ops;
  282. op->op = GRPC_OP_SEND_INITIAL_METADATA;
  283. op->data.send_initial_metadata.count = 0;
  284. op->flags = 0;
  285. op->reserved = nullptr;
  286. op++;
  287. op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
  288. op->data.recv_close_on_server.cancelled = &was_cancelled;
  289. op->flags = 0;
  290. op->reserved = nullptr;
  291. op++;
  292. error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(101),
  293. nullptr);
  294. GPR_ASSERT(GRPC_CALL_OK == error);
  295. for (i = 0; i < 30; i++) {
  296. request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
  297. response_payload = grpc_raw_byte_buffer_create(&response_payload_slice, 1);
  298. memset(ops, 0, sizeof(ops));
  299. op = ops;
  300. op->op = GRPC_OP_SEND_MESSAGE;
  301. op->data.send_message.send_message = request_payload;
  302. op->flags = 0;
  303. op->reserved = nullptr;
  304. op++;
  305. op->op = GRPC_OP_RECV_MESSAGE;
  306. op->data.recv_message.recv_message = &response_payload_recv;
  307. op->flags = 0;
  308. op->reserved = nullptr;
  309. op++;
  310. error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(2),
  311. nullptr);
  312. GPR_ASSERT(GRPC_CALL_OK == error);
  313. memset(ops, 0, sizeof(ops));
  314. op = ops;
  315. op->op = GRPC_OP_RECV_MESSAGE;
  316. op->data.recv_message.recv_message = &request_payload_recv;
  317. op->flags = 0;
  318. op->reserved = nullptr;
  319. op++;
  320. error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
  321. tag(102), nullptr);
  322. GPR_ASSERT(GRPC_CALL_OK == error);
  323. CQ_EXPECT_COMPLETION(cqv, tag(102), 1);
  324. cq_verify(cqv);
  325. memset(ops, 0, sizeof(ops));
  326. op = ops;
  327. op->op = GRPC_OP_SEND_MESSAGE;
  328. op->data.send_message.send_message = response_payload;
  329. op->flags = 0;
  330. op->reserved = nullptr;
  331. op++;
  332. error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops),
  333. tag(103), nullptr);
  334. GPR_ASSERT(GRPC_CALL_OK == error);
  335. CQ_EXPECT_COMPLETION(cqv, tag(103), 1);
  336. CQ_EXPECT_COMPLETION(cqv, tag(2), 1);
  337. cq_verify(cqv);
  338. grpc_byte_buffer_destroy(request_payload);
  339. grpc_byte_buffer_destroy(response_payload);
  340. grpc_byte_buffer_destroy(request_payload_recv);
  341. grpc_byte_buffer_destroy(response_payload_recv);
  342. /* Sleep for a short interval to check if the client sends any pings */
  343. gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(kPingIntervalMS));
  344. }
  345. grpc_slice_unref(request_payload_slice);
  346. grpc_slice_unref(response_payload_slice);
  347. memset(ops, 0, sizeof(ops));
  348. op = ops;
  349. op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
  350. op->flags = 0;
  351. op->reserved = nullptr;
  352. op++;
  353. error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(3),
  354. nullptr);
  355. GPR_ASSERT(GRPC_CALL_OK == error);
  356. memset(ops, 0, sizeof(ops));
  357. op = ops;
  358. op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
  359. op->data.send_status_from_server.trailing_metadata_count = 0;
  360. op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED;
  361. grpc_slice status_details = grpc_slice_from_static_string("xyz");
  362. op->data.send_status_from_server.status_details = &status_details;
  363. op->flags = 0;
  364. op->reserved = nullptr;
  365. op++;
  366. error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(104),
  367. nullptr);
  368. GPR_ASSERT(GRPC_CALL_OK == error);
  369. CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
  370. CQ_EXPECT_COMPLETION(cqv, tag(3), 1);
  371. CQ_EXPECT_COMPLETION(cqv, tag(101), 1);
  372. CQ_EXPECT_COMPLETION(cqv, tag(104), 1);
  373. cq_verify(cqv);
  374. grpc_call_unref(c);
  375. grpc_call_unref(s);
  376. cq_verifier_destroy(cqv);
  377. grpc_metadata_array_destroy(&initial_metadata_recv);
  378. grpc_metadata_array_destroy(&trailing_metadata_recv);
  379. grpc_metadata_array_destroy(&request_metadata_recv);
  380. grpc_call_details_destroy(&call_details);
  381. grpc_slice_unref(details);
  382. end_test(&f);
  383. config.tear_down_data(&f);
  384. }
  385. void keepalive_timeout(grpc_end2end_test_config config) {
  386. test_keepalive_timeout(config);
  387. test_read_delays_keepalive(config);
  388. }
  389. void keepalive_timeout_pre_init(void) {}