byte_stream_test.cc 9.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263
  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 "src/core/lib/transport/byte_stream.h"
  19. #include <grpc/support/alloc.h>
  20. #include <grpc/support/log.h>
  21. #include <grpc/support/useful.h>
  22. #include "src/core/lib/slice/slice_internal.h"
  23. #include "test/core/util/test_config.h"
  24. //
  25. // grpc_slice_buffer_stream tests
  26. //
  27. static void not_called_closure(void* arg, grpc_error* error) {
  28. GPR_ASSERT(false);
  29. }
  30. static void test_slice_buffer_stream_basic(void) {
  31. gpr_log(GPR_DEBUG, "test_slice_buffer_stream_basic");
  32. grpc_core::ExecCtx _local_exec_ctx;
  33. // Create and populate slice buffer.
  34. grpc_slice_buffer buffer;
  35. grpc_slice_buffer_init(&buffer);
  36. grpc_slice input[] = {
  37. grpc_slice_from_static_string("foo"),
  38. grpc_slice_from_static_string("bar"),
  39. };
  40. for (size_t i = 0; i < GPR_ARRAY_SIZE(input); ++i) {
  41. grpc_slice_buffer_add(&buffer, input[i]);
  42. }
  43. // Create byte stream.
  44. grpc_slice_buffer_stream stream;
  45. grpc_slice_buffer_stream_init(&stream, &buffer, 0);
  46. GPR_ASSERT(stream.base.length == 6);
  47. grpc_closure closure;
  48. GRPC_CLOSURE_INIT(&closure, not_called_closure, NULL,
  49. grpc_schedule_on_exec_ctx);
  50. // Read each slice. Note that next() always returns synchronously.
  51. for (size_t i = 0; i < GPR_ARRAY_SIZE(input); ++i) {
  52. GPR_ASSERT(grpc_byte_stream_next(&stream.base, ~(size_t)0, &closure));
  53. grpc_slice output;
  54. grpc_error* error = grpc_byte_stream_pull(&stream.base, &output);
  55. GPR_ASSERT(error == GRPC_ERROR_NONE);
  56. GPR_ASSERT(grpc_slice_eq(input[i], output));
  57. grpc_slice_unref_internal(output);
  58. }
  59. // Clean up.
  60. grpc_byte_stream_destroy(&stream.base);
  61. grpc_slice_buffer_destroy_internal(&buffer);
  62. }
  63. static void test_slice_buffer_stream_shutdown(void) {
  64. gpr_log(GPR_DEBUG, "test_slice_buffer_stream_shutdown");
  65. grpc_core::ExecCtx _local_exec_ctx;
  66. // Create and populate slice buffer.
  67. grpc_slice_buffer buffer;
  68. grpc_slice_buffer_init(&buffer);
  69. grpc_slice input[] = {
  70. grpc_slice_from_static_string("foo"),
  71. grpc_slice_from_static_string("bar"),
  72. };
  73. for (size_t i = 0; i < GPR_ARRAY_SIZE(input); ++i) {
  74. grpc_slice_buffer_add(&buffer, input[i]);
  75. }
  76. // Create byte stream.
  77. grpc_slice_buffer_stream stream;
  78. grpc_slice_buffer_stream_init(&stream, &buffer, 0);
  79. GPR_ASSERT(stream.base.length == 6);
  80. grpc_closure closure;
  81. GRPC_CLOSURE_INIT(&closure, not_called_closure, NULL,
  82. grpc_schedule_on_exec_ctx);
  83. // Read the first slice.
  84. GPR_ASSERT(grpc_byte_stream_next(&stream.base, ~(size_t)0, &closure));
  85. grpc_slice output;
  86. grpc_error* error = grpc_byte_stream_pull(&stream.base, &output);
  87. GPR_ASSERT(error == GRPC_ERROR_NONE);
  88. GPR_ASSERT(grpc_slice_eq(input[0], output));
  89. grpc_slice_unref_internal(output);
  90. // Now shutdown.
  91. grpc_error* shutdown_error =
  92. GRPC_ERROR_CREATE_FROM_STATIC_STRING("shutdown error");
  93. grpc_byte_stream_shutdown(&stream.base, GRPC_ERROR_REF(shutdown_error));
  94. // After shutdown, the next pull() should return the error.
  95. GPR_ASSERT(grpc_byte_stream_next(&stream.base, ~(size_t)0, &closure));
  96. error = grpc_byte_stream_pull(&stream.base, &output);
  97. GPR_ASSERT(error == shutdown_error);
  98. GRPC_ERROR_UNREF(error);
  99. GRPC_ERROR_UNREF(shutdown_error);
  100. // Clean up.
  101. grpc_byte_stream_destroy(&stream.base);
  102. grpc_slice_buffer_destroy_internal(&buffer);
  103. }
  104. //
  105. // grpc_caching_byte_stream tests
  106. //
  107. static void test_caching_byte_stream_basic(void) {
  108. gpr_log(GPR_DEBUG, "test_caching_byte_stream_basic");
  109. grpc_core::ExecCtx _local_exec_ctx;
  110. // Create and populate slice buffer byte stream.
  111. grpc_slice_buffer buffer;
  112. grpc_slice_buffer_init(&buffer);
  113. grpc_slice input[] = {
  114. grpc_slice_from_static_string("foo"),
  115. grpc_slice_from_static_string("bar"),
  116. };
  117. for (size_t i = 0; i < GPR_ARRAY_SIZE(input); ++i) {
  118. grpc_slice_buffer_add(&buffer, input[i]);
  119. }
  120. grpc_slice_buffer_stream underlying_stream;
  121. grpc_slice_buffer_stream_init(&underlying_stream, &buffer, 0);
  122. // Create cache and caching stream.
  123. grpc_byte_stream_cache cache;
  124. grpc_byte_stream_cache_init(&cache, &underlying_stream.base);
  125. grpc_caching_byte_stream stream;
  126. grpc_caching_byte_stream_init(&stream, &cache);
  127. grpc_closure closure;
  128. GRPC_CLOSURE_INIT(&closure, not_called_closure, NULL,
  129. grpc_schedule_on_exec_ctx);
  130. // Read each slice. Note that next() always returns synchronously,
  131. // because the underlying byte stream always does.
  132. for (size_t i = 0; i < GPR_ARRAY_SIZE(input); ++i) {
  133. GPR_ASSERT(grpc_byte_stream_next(&stream.base, ~(size_t)0, &closure));
  134. grpc_slice output;
  135. grpc_error* error = grpc_byte_stream_pull(&stream.base, &output);
  136. GPR_ASSERT(error == GRPC_ERROR_NONE);
  137. GPR_ASSERT(grpc_slice_eq(input[i], output));
  138. grpc_slice_unref_internal(output);
  139. }
  140. // Clean up.
  141. grpc_byte_stream_destroy(&stream.base);
  142. grpc_byte_stream_cache_destroy(&cache);
  143. grpc_slice_buffer_destroy_internal(&buffer);
  144. }
  145. static void test_caching_byte_stream_reset(void) {
  146. gpr_log(GPR_DEBUG, "test_caching_byte_stream_reset");
  147. grpc_core::ExecCtx _local_exec_ctx;
  148. // Create and populate slice buffer byte stream.
  149. grpc_slice_buffer buffer;
  150. grpc_slice_buffer_init(&buffer);
  151. grpc_slice input[] = {
  152. grpc_slice_from_static_string("foo"),
  153. grpc_slice_from_static_string("bar"),
  154. };
  155. for (size_t i = 0; i < GPR_ARRAY_SIZE(input); ++i) {
  156. grpc_slice_buffer_add(&buffer, input[i]);
  157. }
  158. grpc_slice_buffer_stream underlying_stream;
  159. grpc_slice_buffer_stream_init(&underlying_stream, &buffer, 0);
  160. // Create cache and caching stream.
  161. grpc_byte_stream_cache cache;
  162. grpc_byte_stream_cache_init(&cache, &underlying_stream.base);
  163. grpc_caching_byte_stream stream;
  164. grpc_caching_byte_stream_init(&stream, &cache);
  165. grpc_closure closure;
  166. GRPC_CLOSURE_INIT(&closure, not_called_closure, NULL,
  167. grpc_schedule_on_exec_ctx);
  168. // Read one slice.
  169. GPR_ASSERT(grpc_byte_stream_next(&stream.base, ~(size_t)0, &closure));
  170. grpc_slice output;
  171. grpc_error* error = grpc_byte_stream_pull(&stream.base, &output);
  172. GPR_ASSERT(error == GRPC_ERROR_NONE);
  173. GPR_ASSERT(grpc_slice_eq(input[0], output));
  174. grpc_slice_unref_internal(output);
  175. // Reset the caching stream. The reads should start over from the
  176. // first slice.
  177. grpc_caching_byte_stream_reset(&stream);
  178. for (size_t i = 0; i < GPR_ARRAY_SIZE(input); ++i) {
  179. GPR_ASSERT(grpc_byte_stream_next(&stream.base, ~(size_t)0, &closure));
  180. error = grpc_byte_stream_pull(&stream.base, &output);
  181. GPR_ASSERT(error == GRPC_ERROR_NONE);
  182. GPR_ASSERT(grpc_slice_eq(input[i], output));
  183. grpc_slice_unref_internal(output);
  184. }
  185. // Clean up.
  186. grpc_byte_stream_destroy(&stream.base);
  187. grpc_byte_stream_cache_destroy(&cache);
  188. grpc_slice_buffer_destroy_internal(&buffer);
  189. }
  190. static void test_caching_byte_stream_shared_cache(void) {
  191. gpr_log(GPR_DEBUG, "test_caching_byte_stream_shared_cache");
  192. grpc_core::ExecCtx _local_exec_ctx;
  193. // Create and populate slice buffer byte stream.
  194. grpc_slice_buffer buffer;
  195. grpc_slice_buffer_init(&buffer);
  196. grpc_slice input[] = {
  197. grpc_slice_from_static_string("foo"),
  198. grpc_slice_from_static_string("bar"),
  199. };
  200. for (size_t i = 0; i < GPR_ARRAY_SIZE(input); ++i) {
  201. grpc_slice_buffer_add(&buffer, input[i]);
  202. }
  203. grpc_slice_buffer_stream underlying_stream;
  204. grpc_slice_buffer_stream_init(&underlying_stream, &buffer, 0);
  205. // Create cache and two caching streams.
  206. grpc_byte_stream_cache cache;
  207. grpc_byte_stream_cache_init(&cache, &underlying_stream.base);
  208. grpc_caching_byte_stream stream1;
  209. grpc_caching_byte_stream_init(&stream1, &cache);
  210. grpc_caching_byte_stream stream2;
  211. grpc_caching_byte_stream_init(&stream2, &cache);
  212. grpc_closure closure;
  213. GRPC_CLOSURE_INIT(&closure, not_called_closure, NULL,
  214. grpc_schedule_on_exec_ctx);
  215. // Read one slice from stream1.
  216. GPR_ASSERT(grpc_byte_stream_next(&stream1.base, ~(size_t)0, &closure));
  217. grpc_slice output;
  218. grpc_error* error = grpc_byte_stream_pull(&stream1.base, &output);
  219. GPR_ASSERT(error == GRPC_ERROR_NONE);
  220. GPR_ASSERT(grpc_slice_eq(input[0], output));
  221. grpc_slice_unref_internal(output);
  222. // Read all slices from stream2.
  223. for (size_t i = 0; i < GPR_ARRAY_SIZE(input); ++i) {
  224. GPR_ASSERT(grpc_byte_stream_next(&stream2.base, ~(size_t)0, &closure));
  225. error = grpc_byte_stream_pull(&stream2.base, &output);
  226. GPR_ASSERT(error == GRPC_ERROR_NONE);
  227. GPR_ASSERT(grpc_slice_eq(input[i], output));
  228. grpc_slice_unref_internal(output);
  229. }
  230. // Now read the second slice from stream1.
  231. GPR_ASSERT(grpc_byte_stream_next(&stream1.base, ~(size_t)0, &closure));
  232. error = grpc_byte_stream_pull(&stream1.base, &output);
  233. GPR_ASSERT(error == GRPC_ERROR_NONE);
  234. GPR_ASSERT(grpc_slice_eq(input[1], output));
  235. grpc_slice_unref_internal(output);
  236. // Clean up.
  237. grpc_byte_stream_destroy(&stream1.base);
  238. grpc_byte_stream_destroy(&stream2.base);
  239. grpc_byte_stream_cache_destroy(&cache);
  240. grpc_slice_buffer_destroy_internal(&buffer);
  241. }
  242. int main(int argc, char** argv) {
  243. grpc_test_init(argc, argv);
  244. test_slice_buffer_stream_basic();
  245. test_slice_buffer_stream_shutdown();
  246. test_caching_byte_stream_basic();
  247. test_caching_byte_stream_reset();
  248. test_caching_byte_stream_shared_cache();
  249. return 0;
  250. }