channel_args_test.cc 7.8 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220
  1. /*
  2. *
  3. * Copyright 2015 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/channel/channel_args.h"
  19. #include <string.h>
  20. #include <grpc/grpc_security.h>
  21. #include <grpc/impl/codegen/grpc_types.h>
  22. #include <grpc/impl/codegen/log.h>
  23. #include <grpc/support/log.h>
  24. #include "src/core/lib/channel/channel_stack.h"
  25. #include "src/core/lib/gpr/useful.h"
  26. #include "src/core/lib/iomgr/exec_ctx.h"
  27. #include "src/core/lib/surface/channel.h"
  28. #include "test/core/util/test_config.h"
  29. static void test_create(void) {
  30. grpc_core::ExecCtx exec_ctx;
  31. grpc_arg to_add[2];
  32. grpc_channel_args* ch_args;
  33. to_add[0] =
  34. grpc_channel_arg_integer_create(const_cast<char*>("int_arg"), 123);
  35. to_add[1] = grpc_channel_arg_string_create(const_cast<char*>("str key"),
  36. const_cast<char*>("str value"));
  37. ch_args = grpc_channel_args_copy_and_add(nullptr, to_add, 2);
  38. GPR_ASSERT(ch_args->num_args == 2);
  39. GPR_ASSERT(strcmp(ch_args->args[0].key, to_add[0].key) == 0);
  40. GPR_ASSERT(ch_args->args[0].type == to_add[0].type);
  41. GPR_ASSERT(ch_args->args[0].value.integer == to_add[0].value.integer);
  42. GPR_ASSERT(strcmp(ch_args->args[1].key, to_add[1].key) == 0);
  43. GPR_ASSERT(ch_args->args[1].type == to_add[1].type);
  44. GPR_ASSERT(strcmp(ch_args->args[1].value.string, to_add[1].value.string) ==
  45. 0);
  46. grpc_channel_args_destroy(ch_args);
  47. }
  48. struct fake_class {
  49. int foo;
  50. };
  51. static void* fake_pointer_arg_copy(void* arg) {
  52. gpr_log(GPR_DEBUG, "fake_pointer_arg_copy");
  53. fake_class* fc = static_cast<fake_class*>(arg);
  54. fake_class* new_fc = static_cast<fake_class*>(gpr_malloc(sizeof(fake_class)));
  55. new_fc->foo = fc->foo;
  56. return new_fc;
  57. }
  58. static void fake_pointer_arg_destroy(void* arg) {
  59. gpr_log(GPR_DEBUG, "fake_pointer_arg_destroy");
  60. fake_class* fc = static_cast<fake_class*>(arg);
  61. gpr_free(fc);
  62. }
  63. static int fake_pointer_cmp(void* a, void* b) {
  64. return grpc_core::QsortCompare(a, b);
  65. }
  66. static const grpc_arg_pointer_vtable fake_pointer_arg_vtable = {
  67. fake_pointer_arg_copy, fake_pointer_arg_destroy, fake_pointer_cmp};
  68. static void test_channel_create_with_args(void) {
  69. grpc_arg client_a[3];
  70. client_a[0] =
  71. grpc_channel_arg_integer_create(const_cast<char*>("arg_int"), 0);
  72. client_a[1] = grpc_channel_arg_string_create(
  73. const_cast<char*>("arg_str"), const_cast<char*>("arg_str_val"));
  74. // allocated and adds custom pointer arg
  75. fake_class* fc = static_cast<fake_class*>(gpr_malloc(sizeof(fake_class)));
  76. fc->foo = 42;
  77. client_a[2] = grpc_channel_arg_pointer_create(
  78. const_cast<char*>("arg_pointer"), fc, &fake_pointer_arg_vtable);
  79. // creates channel
  80. grpc_channel_args client_args = {GPR_ARRAY_SIZE(client_a), client_a};
  81. grpc_channel_credentials* creds = grpc_insecure_credentials_create();
  82. grpc_channel* c = grpc_channel_create("fake_target", creds, &client_args);
  83. grpc_channel_credentials_release(creds);
  84. // user is can free the memory they allocated here
  85. gpr_free(fc);
  86. grpc_channel_destroy(c);
  87. }
  88. grpc_channel_args* mutate_channel_args(const char* target,
  89. grpc_channel_args* old_args,
  90. grpc_channel_stack_type /*type*/) {
  91. GPR_ASSERT(old_args != nullptr);
  92. GPR_ASSERT(grpc_channel_args_find(old_args, "arg_int")->value.integer == 0);
  93. GPR_ASSERT(strcmp(grpc_channel_args_find(old_args, "arg_str")->value.string,
  94. "arg_str_val") == 0);
  95. GPR_ASSERT(
  96. grpc_channel_args_find(old_args, "arg_pointer")->value.pointer.vtable ==
  97. &fake_pointer_arg_vtable);
  98. if (strcmp(target, "no_op_mutator") == 0) {
  99. return old_args;
  100. }
  101. GPR_ASSERT(strcmp(target, "minimal_stack_mutator") == 0);
  102. const char* args_to_remove[] = {"arg_int", "arg_str", "arg_pointer"};
  103. grpc_arg no_deadline_filter_arg = grpc_channel_arg_integer_create(
  104. const_cast<char*>(GRPC_ARG_MINIMAL_STACK), 1);
  105. grpc_channel_args* new_args = nullptr;
  106. new_args = grpc_channel_args_copy_and_add_and_remove(
  107. old_args, args_to_remove, GPR_ARRAY_SIZE(args_to_remove),
  108. &no_deadline_filter_arg, 1);
  109. grpc_channel_args_destroy(old_args);
  110. return new_args;
  111. }
  112. // Minimal stack should not have client_idle filter
  113. static bool channel_has_client_idle_filter(grpc_channel* c) {
  114. grpc_channel_stack* stack = grpc_channel_get_channel_stack(c);
  115. for (size_t i = 0; i < stack->count; i++) {
  116. if (strcmp(grpc_channel_stack_element(stack, i)->filter->name,
  117. "client_idle") == 0) {
  118. return true;
  119. }
  120. }
  121. return false;
  122. }
  123. static void test_channel_create_with_global_mutator(void) {
  124. grpc_channel_args_set_client_channel_creation_mutator(mutate_channel_args);
  125. // We also add some custom args to make sure the ownership is correct.
  126. grpc_arg client_a[3];
  127. client_a[0] =
  128. grpc_channel_arg_integer_create(const_cast<char*>("arg_int"), 0);
  129. client_a[1] = grpc_channel_arg_string_create(
  130. const_cast<char*>("arg_str"), const_cast<char*>("arg_str_val"));
  131. // allocated and adds custom pointer arg
  132. fake_class* fc = static_cast<fake_class*>(gpr_malloc(sizeof(fake_class)));
  133. fc->foo = 42;
  134. client_a[2] = grpc_channel_arg_pointer_create(
  135. const_cast<char*>("arg_pointer"), fc, &fake_pointer_arg_vtable);
  136. // creates channels
  137. grpc_channel_args client_args = {GPR_ARRAY_SIZE(client_a), client_a};
  138. grpc_channel_credentials* creds = grpc_insecure_credentials_create();
  139. grpc_channel* c = grpc_channel_create("no_op_mutator", creds, &client_args);
  140. grpc_channel_credentials_release(creds);
  141. GPR_ASSERT(channel_has_client_idle_filter(c));
  142. grpc_channel_destroy(c);
  143. grpc_channel_credentials* another_creds = grpc_insecure_credentials_create();
  144. c = grpc_channel_create("minimal_stack_mutator", another_creds, &client_args);
  145. grpc_channel_credentials_release(another_creds);
  146. GPR_ASSERT(channel_has_client_idle_filter(c) == false);
  147. grpc_channel_destroy(c);
  148. gpr_free(fc);
  149. auto mutator = grpc_channel_args_get_client_channel_creation_mutator();
  150. GPR_ASSERT(mutator == &mutate_channel_args);
  151. }
  152. static void test_server_create_with_args(void) {
  153. grpc_arg server_a[3];
  154. // adds integer arg
  155. server_a[0].type = GRPC_ARG_INTEGER;
  156. server_a[0].key = const_cast<char*>("arg_int");
  157. server_a[0].value.integer = 0;
  158. // adds const str arg
  159. server_a[1].type = GRPC_ARG_STRING;
  160. server_a[1].key = const_cast<char*>("arg_str");
  161. server_a[1].value.string = const_cast<char*>("arg_str_val");
  162. // allocated and adds custom pointer arg
  163. fake_class* fc = static_cast<fake_class*>(gpr_malloc(sizeof(fake_class)));
  164. fc->foo = 42;
  165. server_a[2].type = GRPC_ARG_POINTER;
  166. server_a[2].key = const_cast<char*>("arg_pointer");
  167. server_a[2].value.pointer.vtable = &fake_pointer_arg_vtable;
  168. server_a[2].value.pointer.p = fc;
  169. // creates server
  170. grpc_channel_args server_args = {GPR_ARRAY_SIZE(server_a), server_a};
  171. grpc_server* s = grpc_server_create(&server_args, nullptr);
  172. // user is can free the memory they allocated here
  173. gpr_free(fc);
  174. grpc_server_destroy(s);
  175. }
  176. int main(int argc, char** argv) {
  177. grpc::testing::TestEnvironment env(argc, argv);
  178. grpc_init();
  179. test_create();
  180. test_channel_create_with_args();
  181. test_server_create_with_args();
  182. // This has to be the last test.
  183. // TODO(markdroth): re-enable this test once client_idle is re-enabled
  184. // test_channel_create_with_global_mutator();
  185. grpc_shutdown();
  186. return 0;
  187. }