compressed_payload.c 16 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434
  1. /*
  2. *
  3. * Copyright 2015, Google Inc.
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions are
  8. * met:
  9. *
  10. * * Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * * Redistributions in binary form must reproduce the above
  13. * copyright notice, this list of conditions and the following disclaimer
  14. * in the documentation and/or other materials provided with the
  15. * distribution.
  16. * * Neither the name of Google Inc. nor the names of its
  17. * contributors may be used to endorse or promote products derived from
  18. * this software without specific prior written permission.
  19. *
  20. * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
  21. * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
  22. * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
  23. * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
  24. * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
  25. * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
  26. * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
  27. * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
  28. * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
  29. * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
  30. * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
  31. *
  32. */
  33. #include "test/core/end2end/end2end_tests.h"
  34. #include <stdio.h>
  35. #include <string.h>
  36. #include <grpc/byte_buffer.h>
  37. #include <grpc/byte_buffer_reader.h>
  38. #include <grpc/impl/codegen/compression_types.h>
  39. #include <grpc/support/alloc.h>
  40. #include <grpc/support/log.h>
  41. #include <grpc/support/time.h>
  42. #include <grpc/support/useful.h>
  43. #include "src/core/lib/channel/channel_args.h"
  44. #include "src/core/lib/surface/call.h"
  45. #include "src/core/lib/surface/call_test_only.h"
  46. #include "test/core/end2end/cq_verifier.h"
  47. enum { TIMEOUT = 200000 };
  48. static void *tag(intptr_t t) { return (void *)t; }
  49. static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
  50. const char *test_name,
  51. grpc_channel_args *client_args,
  52. grpc_channel_args *server_args) {
  53. grpc_end2end_test_fixture f;
  54. gpr_log(GPR_INFO, "%s/%s", test_name, config.name);
  55. f = config.create_fixture(client_args, server_args);
  56. config.init_server(&f, server_args);
  57. config.init_client(&f, client_args);
  58. return f;
  59. }
  60. static gpr_timespec n_seconds_time(int n) {
  61. return GRPC_TIMEOUT_SECONDS_TO_DEADLINE(n);
  62. }
  63. static gpr_timespec five_seconds_time(void) { return n_seconds_time(5); }
  64. static void drain_cq(grpc_completion_queue *cq) {
  65. grpc_event ev;
  66. do {
  67. ev = grpc_completion_queue_next(cq, five_seconds_time(), NULL);
  68. } while (ev.type != GRPC_QUEUE_SHUTDOWN);
  69. }
  70. static void shutdown_server(grpc_end2end_test_fixture *f) {
  71. if (!f->server) return;
  72. grpc_server_shutdown_and_notify(f->server, f->cq, tag(1000));
  73. GPR_ASSERT(grpc_completion_queue_pluck(
  74. f->cq, tag(1000), GRPC_TIMEOUT_SECONDS_TO_DEADLINE(5), NULL)
  75. .type == GRPC_OP_COMPLETE);
  76. grpc_server_destroy(f->server);
  77. f->server = NULL;
  78. }
  79. static void shutdown_client(grpc_end2end_test_fixture *f) {
  80. if (!f->client) return;
  81. grpc_channel_destroy(f->client);
  82. f->client = NULL;
  83. }
  84. static void end_test(grpc_end2end_test_fixture *f) {
  85. shutdown_server(f);
  86. shutdown_client(f);
  87. grpc_completion_queue_shutdown(f->cq);
  88. drain_cq(f->cq);
  89. grpc_completion_queue_destroy(f->cq);
  90. }
  91. static void request_with_payload_template(
  92. grpc_end2end_test_config config, const char *test_name,
  93. uint32_t client_send_flags_bitmask,
  94. grpc_compression_algorithm default_client_channel_compression_algorithm,
  95. grpc_compression_algorithm default_server_channel_compression_algorithm,
  96. grpc_compression_algorithm expected_algorithm_from_client,
  97. grpc_compression_algorithm expected_algorithm_from_server,
  98. grpc_metadata *client_init_metadata, bool set_server_level,
  99. grpc_compression_level server_compression_level) {
  100. grpc_call *c;
  101. grpc_call *s;
  102. gpr_slice request_payload_slice;
  103. grpc_byte_buffer *request_payload;
  104. gpr_timespec deadline = five_seconds_time();
  105. grpc_channel_args *client_args;
  106. grpc_channel_args *server_args;
  107. grpc_end2end_test_fixture f;
  108. grpc_op ops[6];
  109. grpc_op *op;
  110. grpc_metadata_array initial_metadata_recv;
  111. grpc_metadata_array trailing_metadata_recv;
  112. grpc_metadata_array request_metadata_recv;
  113. grpc_byte_buffer *request_payload_recv = NULL;
  114. grpc_byte_buffer *response_payload;
  115. grpc_byte_buffer *response_payload_recv;
  116. grpc_call_details call_details;
  117. grpc_status_code status;
  118. grpc_call_error error;
  119. char *details = NULL;
  120. size_t details_capacity = 0;
  121. int was_cancelled = 2;
  122. cq_verifier *cqv;
  123. char request_str[1024];
  124. char response_str[1024];
  125. memset(request_str, 'x', 1023);
  126. request_str[1023] = '\0';
  127. memset(response_str, 'y', 1023);
  128. response_str[1023] = '\0';
  129. request_payload_slice = gpr_slice_from_copied_string(request_str);
  130. gpr_slice response_payload_slice = gpr_slice_from_copied_string(response_str);
  131. client_args = grpc_channel_args_set_compression_algorithm(
  132. NULL, default_client_channel_compression_algorithm);
  133. server_args = grpc_channel_args_set_compression_algorithm(
  134. NULL, default_server_channel_compression_algorithm);
  135. f = begin_test(config, test_name, client_args, server_args);
  136. cqv = cq_verifier_create(f.cq);
  137. c = grpc_channel_create_call(f.client, NULL, GRPC_PROPAGATE_DEFAULTS, f.cq,
  138. "/foo", "foo.test.google.fr", deadline, NULL);
  139. GPR_ASSERT(c);
  140. grpc_metadata_array_init(&initial_metadata_recv);
  141. grpc_metadata_array_init(&trailing_metadata_recv);
  142. grpc_metadata_array_init(&request_metadata_recv);
  143. grpc_call_details_init(&call_details);
  144. memset(ops, 0, sizeof(ops));
  145. op = ops;
  146. op->op = GRPC_OP_SEND_INITIAL_METADATA;
  147. if (client_init_metadata != NULL) {
  148. op->data.send_initial_metadata.count = 1;
  149. op->data.send_initial_metadata.metadata = client_init_metadata;
  150. } else {
  151. op->data.send_initial_metadata.count = 0;
  152. }
  153. op->flags = 0;
  154. op->reserved = NULL;
  155. op++;
  156. op->op = GRPC_OP_RECV_INITIAL_METADATA;
  157. op->data.recv_initial_metadata = &initial_metadata_recv;
  158. op->flags = 0;
  159. op->reserved = NULL;
  160. op++;
  161. op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
  162. op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
  163. op->data.recv_status_on_client.status = &status;
  164. op->data.recv_status_on_client.status_details = &details;
  165. op->data.recv_status_on_client.status_details_capacity = &details_capacity;
  166. op->flags = 0;
  167. op->reserved = NULL;
  168. op++;
  169. error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), NULL);
  170. GPR_ASSERT(GRPC_CALL_OK == error);
  171. error =
  172. grpc_server_request_call(f.server, &s, &call_details,
  173. &request_metadata_recv, f.cq, f.cq, tag(100));
  174. GPR_ASSERT(GRPC_CALL_OK == error);
  175. cq_expect_completion(cqv, tag(100), 1);
  176. cq_verify(cqv);
  177. GPR_ASSERT(
  178. GPR_BITCOUNT(grpc_call_test_only_get_encodings_accepted_by_peer(s)) == 3);
  179. GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
  180. GRPC_COMPRESS_NONE) != 0);
  181. GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
  182. GRPC_COMPRESS_DEFLATE) != 0);
  183. GPR_ASSERT(GPR_BITGET(grpc_call_test_only_get_encodings_accepted_by_peer(s),
  184. GRPC_COMPRESS_GZIP) != 0);
  185. memset(ops, 0, sizeof(ops));
  186. op = ops;
  187. op->op = GRPC_OP_SEND_INITIAL_METADATA;
  188. op->data.send_initial_metadata.count = 0;
  189. if (set_server_level) {
  190. op->data.send_initial_metadata.maybe_compression_level.is_set = true;
  191. op->data.send_initial_metadata.maybe_compression_level.compression_level =
  192. server_compression_level;
  193. }
  194. op->flags = 0;
  195. op->reserved = NULL;
  196. op++;
  197. op->op = GRPC_OP_RECV_CLOSE_ON_SERVER;
  198. op->data.recv_close_on_server.cancelled = &was_cancelled;
  199. op->flags = 0;
  200. op->reserved = NULL;
  201. op++;
  202. error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(101), NULL);
  203. GPR_ASSERT(GRPC_CALL_OK == error);
  204. for (int i = 0; i < 2; i++) {
  205. request_payload = grpc_raw_byte_buffer_create(&request_payload_slice, 1);
  206. response_payload = grpc_raw_byte_buffer_create(&response_payload_slice, 1);
  207. memset(ops, 0, sizeof(ops));
  208. op = ops;
  209. op->op = GRPC_OP_SEND_MESSAGE;
  210. op->data.send_message = request_payload;
  211. op->flags = client_send_flags_bitmask;
  212. op->reserved = NULL;
  213. op++;
  214. op->op = GRPC_OP_RECV_MESSAGE;
  215. op->data.recv_message = &response_payload_recv;
  216. op->flags = 0;
  217. op->reserved = NULL;
  218. op++;
  219. error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), NULL);
  220. GPR_ASSERT(GRPC_CALL_OK == error);
  221. memset(ops, 0, sizeof(ops));
  222. op = ops;
  223. op->op = GRPC_OP_RECV_MESSAGE;
  224. op->data.recv_message = &request_payload_recv;
  225. op->flags = 0;
  226. op->reserved = NULL;
  227. op++;
  228. error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(102), NULL);
  229. GPR_ASSERT(GRPC_CALL_OK == error);
  230. cq_expect_completion(cqv, tag(102), 1);
  231. cq_verify(cqv);
  232. GPR_ASSERT(request_payload_recv->type == GRPC_BB_RAW);
  233. GPR_ASSERT(byte_buffer_eq_string(request_payload_recv, request_str));
  234. GPR_ASSERT(request_payload_recv->data.raw.compression ==
  235. expected_algorithm_from_client);
  236. memset(ops, 0, sizeof(ops));
  237. op = ops;
  238. op->op = GRPC_OP_SEND_MESSAGE;
  239. op->data.send_message = response_payload;
  240. op->flags = 0;
  241. op->reserved = NULL;
  242. op++;
  243. error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(103), NULL);
  244. GPR_ASSERT(GRPC_CALL_OK == error);
  245. cq_expect_completion(cqv, tag(103), 1);
  246. cq_expect_completion(cqv, tag(2), 1);
  247. cq_verify(cqv);
  248. GPR_ASSERT(response_payload_recv->type == GRPC_BB_RAW);
  249. GPR_ASSERT(byte_buffer_eq_string(response_payload_recv, response_str));
  250. if (server_compression_level > GRPC_COMPRESS_LEVEL_NONE) {
  251. const grpc_compression_algorithm algo_for_server_level =
  252. grpc_call_compression_for_level(s, server_compression_level);
  253. GPR_ASSERT(response_payload_recv->data.raw.compression ==
  254. algo_for_server_level);
  255. } else {
  256. GPR_ASSERT(response_payload_recv->data.raw.compression ==
  257. expected_algorithm_from_server);
  258. }
  259. grpc_byte_buffer_destroy(request_payload);
  260. grpc_byte_buffer_destroy(response_payload);
  261. grpc_byte_buffer_destroy(request_payload_recv);
  262. grpc_byte_buffer_destroy(response_payload_recv);
  263. }
  264. gpr_slice_unref(request_payload_slice);
  265. gpr_slice_unref(response_payload_slice);
  266. memset(ops, 0, sizeof(ops));
  267. op = ops;
  268. op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
  269. op->flags = 0;
  270. op->reserved = NULL;
  271. op++;
  272. error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(3), NULL);
  273. GPR_ASSERT(GRPC_CALL_OK == error);
  274. memset(ops, 0, sizeof(ops));
  275. op = ops;
  276. op->op = GRPC_OP_SEND_STATUS_FROM_SERVER;
  277. op->data.send_status_from_server.trailing_metadata_count = 0;
  278. op->data.send_status_from_server.status = GRPC_STATUS_OK;
  279. op->data.send_status_from_server.status_details = "xyz";
  280. op->flags = 0;
  281. op->reserved = NULL;
  282. op++;
  283. error = grpc_call_start_batch(s, ops, (size_t)(op - ops), tag(104), NULL);
  284. GPR_ASSERT(GRPC_CALL_OK == error);
  285. cq_expect_completion(cqv, tag(1), 1);
  286. cq_expect_completion(cqv, tag(3), 1);
  287. cq_expect_completion(cqv, tag(101), 1);
  288. cq_expect_completion(cqv, tag(104), 1);
  289. cq_verify(cqv);
  290. GPR_ASSERT(status == GRPC_STATUS_OK);
  291. GPR_ASSERT(0 == strcmp(details, "xyz"));
  292. GPR_ASSERT(0 == strcmp(call_details.method, "/foo"));
  293. GPR_ASSERT(0 == strcmp(call_details.host, "foo.test.google.fr"));
  294. GPR_ASSERT(was_cancelled == 0);
  295. gpr_free(details);
  296. grpc_metadata_array_destroy(&initial_metadata_recv);
  297. grpc_metadata_array_destroy(&trailing_metadata_recv);
  298. grpc_metadata_array_destroy(&request_metadata_recv);
  299. grpc_call_details_destroy(&call_details);
  300. grpc_call_destroy(c);
  301. grpc_call_destroy(s);
  302. cq_verifier_destroy(cqv);
  303. grpc_channel_args_destroy(client_args);
  304. grpc_channel_args_destroy(server_args);
  305. end_test(&f);
  306. config.tear_down_data(&f);
  307. }
  308. static void test_invoke_request_with_exceptionally_uncompressed_payload(
  309. grpc_end2end_test_config config) {
  310. request_with_payload_template(
  311. config, "test_invoke_request_with_exceptionally_uncompressed_payload",
  312. GRPC_WRITE_NO_COMPRESS, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP,
  313. GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP, NULL, false,
  314. /* ignored */ GRPC_COMPRESS_LEVEL_NONE);
  315. }
  316. static void test_invoke_request_with_uncompressed_payload(
  317. grpc_end2end_test_config config) {
  318. request_with_payload_template(
  319. config, "test_invoke_request_with_uncompressed_payload", 0,
  320. GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE,
  321. GRPC_COMPRESS_NONE, NULL, false, /* ignored */ GRPC_COMPRESS_LEVEL_NONE);
  322. }
  323. static void test_invoke_request_with_compressed_payload(
  324. grpc_end2end_test_config config) {
  325. request_with_payload_template(
  326. config, "test_invoke_request_with_compressed_payload", 0,
  327. GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP, GRPC_COMPRESS_GZIP,
  328. GRPC_COMPRESS_GZIP, NULL, false, /* ignored */ GRPC_COMPRESS_LEVEL_NONE);
  329. }
  330. static void test_invoke_request_with_server_level(
  331. grpc_end2end_test_config config) {
  332. request_with_payload_template(
  333. config, "test_invoke_request_with_server_level", 0, GRPC_COMPRESS_NONE,
  334. GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE /* ignored */,
  335. NULL, true, GRPC_COMPRESS_LEVEL_HIGH);
  336. }
  337. static void test_invoke_request_with_compressed_payload_md_override(
  338. grpc_end2end_test_config config) {
  339. grpc_metadata gzip_compression_override;
  340. grpc_metadata identity_compression_override;
  341. gzip_compression_override.key = GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY;
  342. gzip_compression_override.value = "gzip";
  343. gzip_compression_override.value_length =
  344. strlen(gzip_compression_override.value);
  345. memset(&gzip_compression_override.internal_data, 0,
  346. sizeof(gzip_compression_override.internal_data));
  347. identity_compression_override.key = GRPC_COMPRESSION_REQUEST_ALGORITHM_MD_KEY;
  348. identity_compression_override.value = "identity";
  349. identity_compression_override.value_length =
  350. strlen(identity_compression_override.value);
  351. memset(&identity_compression_override.internal_data, 0,
  352. sizeof(identity_compression_override.internal_data));
  353. /* Channel default NONE (aka IDENTITY), call override to GZIP */
  354. request_with_payload_template(
  355. config, "test_invoke_request_with_compressed_payload_md_override_1", 0,
  356. GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP,
  357. GRPC_COMPRESS_NONE, &gzip_compression_override, false,
  358. /*ignored*/ GRPC_COMPRESS_LEVEL_NONE);
  359. /* Channel default DEFLATE, call override to GZIP */
  360. request_with_payload_template(
  361. config, "test_invoke_request_with_compressed_payload_md_override_2", 0,
  362. GRPC_COMPRESS_DEFLATE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_GZIP,
  363. GRPC_COMPRESS_NONE, &gzip_compression_override, false,
  364. /*ignored*/ GRPC_COMPRESS_LEVEL_NONE);
  365. /* Channel default DEFLATE, call override to NONE (aka IDENTITY) */
  366. request_with_payload_template(
  367. config, "test_invoke_request_with_compressed_payload_md_override_3", 0,
  368. GRPC_COMPRESS_DEFLATE, GRPC_COMPRESS_NONE, GRPC_COMPRESS_NONE,
  369. GRPC_COMPRESS_NONE, &identity_compression_override, false,
  370. /*ignored*/ GRPC_COMPRESS_LEVEL_NONE);
  371. }
  372. void compressed_payload(grpc_end2end_test_config config) {
  373. test_invoke_request_with_exceptionally_uncompressed_payload(config);
  374. test_invoke_request_with_uncompressed_payload(config);
  375. test_invoke_request_with_compressed_payload(config);
  376. test_invoke_request_with_server_level(config);
  377. test_invoke_request_with_compressed_payload_md_override(config);
  378. }
  379. void compressed_payload_pre_init(void) {}