channel_arguments_test.cc 7.7 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264
  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 <gtest/gtest.h>
  19. #include <grpc/grpc.h>
  20. #include <grpcpp/grpcpp.h>
  21. #include <grpcpp/support/channel_arguments.h>
  22. #include "src/core/lib/gpr/useful.h"
  23. #include "src/core/lib/iomgr/exec_ctx.h"
  24. #include "src/core/lib/iomgr/socket_mutator.h"
  25. #include "test/core/util/test_config.h"
  26. namespace grpc {
  27. namespace testing {
  28. namespace {
  29. // A simple grpc_socket_mutator to be used to test SetSocketMutator
  30. class TestSocketMutator : public grpc_socket_mutator {
  31. public:
  32. TestSocketMutator();
  33. bool MutateFd(int /*fd*/) {
  34. // Do nothing on the fd
  35. return true;
  36. }
  37. };
  38. //
  39. // C API for TestSocketMutator
  40. //
  41. bool test_mutator_mutate_fd(int fd, grpc_socket_mutator* mutator) {
  42. TestSocketMutator* tsm = reinterpret_cast<TestSocketMutator*>(mutator);
  43. return tsm->MutateFd(fd);
  44. }
  45. int test_mutator_compare(grpc_socket_mutator* a, grpc_socket_mutator* b) {
  46. return grpc_core::QsortCompare(a, b);
  47. }
  48. void test_mutator_destroy(grpc_socket_mutator* mutator) {
  49. TestSocketMutator* tsm = reinterpret_cast<TestSocketMutator*>(mutator);
  50. delete tsm;
  51. }
  52. grpc_socket_mutator_vtable test_mutator_vtable = {
  53. test_mutator_mutate_fd, test_mutator_compare, test_mutator_destroy,
  54. nullptr};
  55. //
  56. // TestSocketMutator implementation
  57. //
  58. TestSocketMutator::TestSocketMutator() {
  59. grpc_socket_mutator_init(this, &test_mutator_vtable);
  60. }
  61. } // namespace
  62. class ChannelArgumentsTest : public ::testing::Test {
  63. protected:
  64. ChannelArgumentsTest()
  65. : pointer_vtable_({&ChannelArguments::PointerVtableMembers::Copy,
  66. &ChannelArguments::PointerVtableMembers::Destroy,
  67. &ChannelArguments::PointerVtableMembers::Compare}) {}
  68. void SetChannelArgs(const ChannelArguments& channel_args,
  69. grpc_channel_args* args) {
  70. channel_args.SetChannelArgs(args);
  71. }
  72. static void SetUpTestCase() { grpc_init(); }
  73. static void TearDownTestCase() { grpc_shutdown(); }
  74. std::string GetDefaultUserAgentPrefix() {
  75. std::ostringstream user_agent_prefix;
  76. user_agent_prefix << "grpc-c++/" << Version();
  77. return user_agent_prefix.str();
  78. }
  79. void VerifyDefaultChannelArgs() {
  80. grpc_channel_args args;
  81. SetChannelArgs(channel_args_, &args);
  82. EXPECT_EQ(static_cast<size_t>(1), args.num_args);
  83. EXPECT_STREQ(GRPC_ARG_PRIMARY_USER_AGENT_STRING, args.args[0].key);
  84. EXPECT_EQ(GetDefaultUserAgentPrefix(),
  85. std::string(args.args[0].value.string));
  86. }
  87. bool HasArg(grpc_arg expected_arg) {
  88. grpc_channel_args args;
  89. SetChannelArgs(channel_args_, &args);
  90. for (size_t i = 0; i < args.num_args; i++) {
  91. const grpc_arg& arg = args.args[i];
  92. if (arg.type == expected_arg.type &&
  93. std::string(arg.key) == expected_arg.key) {
  94. if (arg.type == GRPC_ARG_INTEGER) {
  95. return arg.value.integer == expected_arg.value.integer;
  96. } else if (arg.type == GRPC_ARG_STRING) {
  97. return std::string(arg.value.string) == expected_arg.value.string;
  98. } else if (arg.type == GRPC_ARG_POINTER) {
  99. return arg.value.pointer.p == expected_arg.value.pointer.p &&
  100. arg.value.pointer.vtable->copy ==
  101. expected_arg.value.pointer.vtable->copy &&
  102. arg.value.pointer.vtable->destroy ==
  103. expected_arg.value.pointer.vtable->destroy;
  104. }
  105. }
  106. }
  107. return false;
  108. }
  109. grpc_arg_pointer_vtable pointer_vtable_;
  110. ChannelArguments channel_args_;
  111. };
  112. TEST_F(ChannelArgumentsTest, SetInt) {
  113. VerifyDefaultChannelArgs();
  114. std::string key0("key0");
  115. grpc_arg arg0;
  116. arg0.type = GRPC_ARG_INTEGER;
  117. arg0.key = const_cast<char*>(key0.c_str());
  118. arg0.value.integer = 0;
  119. std::string key1("key1");
  120. grpc_arg arg1;
  121. arg1.type = GRPC_ARG_INTEGER;
  122. arg1.key = const_cast<char*>(key1.c_str());
  123. arg1.value.integer = 1;
  124. std::string arg_key0(key0);
  125. channel_args_.SetInt(arg_key0, arg0.value.integer);
  126. // Clear key early to make sure channel_args takes a copy
  127. arg_key0.clear();
  128. EXPECT_TRUE(HasArg(arg0));
  129. std::string arg_key1(key1);
  130. channel_args_.SetInt(arg_key1, arg1.value.integer);
  131. arg_key1.clear();
  132. EXPECT_TRUE(HasArg(arg0));
  133. EXPECT_TRUE(HasArg(arg1));
  134. }
  135. TEST_F(ChannelArgumentsTest, SetString) {
  136. VerifyDefaultChannelArgs();
  137. std::string key0("key0");
  138. std::string val0("val0");
  139. grpc_arg arg0;
  140. arg0.type = GRPC_ARG_STRING;
  141. arg0.key = const_cast<char*>(key0.c_str());
  142. arg0.value.string = const_cast<char*>(val0.c_str());
  143. std::string key1("key1");
  144. std::string val1("val1");
  145. grpc_arg arg1;
  146. arg1.type = GRPC_ARG_STRING;
  147. arg1.key = const_cast<char*>(key1.c_str());
  148. arg1.value.string = const_cast<char*>(val1.c_str());
  149. std::string key(key0);
  150. std::string val(val0);
  151. channel_args_.SetString(key, val);
  152. // Clear key/val early to make sure channel_args takes a copy
  153. key = "";
  154. val = "";
  155. EXPECT_TRUE(HasArg(arg0));
  156. key = key1;
  157. val = val1;
  158. channel_args_.SetString(key, val);
  159. // Clear key/val early to make sure channel_args takes a copy
  160. key = "";
  161. val = "";
  162. EXPECT_TRUE(HasArg(arg0));
  163. EXPECT_TRUE(HasArg(arg1));
  164. }
  165. TEST_F(ChannelArgumentsTest, SetPointer) {
  166. VerifyDefaultChannelArgs();
  167. std::string key0("key0");
  168. grpc_arg arg0;
  169. arg0.type = GRPC_ARG_POINTER;
  170. arg0.key = const_cast<char*>(key0.c_str());
  171. arg0.value.pointer.p = &key0;
  172. arg0.value.pointer.vtable = &pointer_vtable_;
  173. std::string key(key0);
  174. channel_args_.SetPointer(key, arg0.value.pointer.p);
  175. EXPECT_TRUE(HasArg(arg0));
  176. }
  177. TEST_F(ChannelArgumentsTest, SetSocketMutator) {
  178. VerifyDefaultChannelArgs();
  179. grpc_arg arg0, arg1;
  180. TestSocketMutator* mutator0 = new TestSocketMutator();
  181. TestSocketMutator* mutator1 = new TestSocketMutator();
  182. arg0 = grpc_socket_mutator_to_arg(mutator0);
  183. arg1 = grpc_socket_mutator_to_arg(mutator1);
  184. channel_args_.SetSocketMutator(mutator0);
  185. EXPECT_TRUE(HasArg(arg0));
  186. // Exercise the copy constructor because we ran some sanity checks in it.
  187. grpc::ChannelArguments new_args{channel_args_};
  188. channel_args_.SetSocketMutator(mutator1);
  189. EXPECT_TRUE(HasArg(arg1));
  190. // arg0 is replaced by arg1
  191. EXPECT_FALSE(HasArg(arg0));
  192. }
  193. TEST_F(ChannelArgumentsTest, SetUserAgentPrefix) {
  194. VerifyDefaultChannelArgs();
  195. std::string prefix("prefix");
  196. std::string whole_prefix = prefix + " " + GetDefaultUserAgentPrefix();
  197. grpc_arg arg0;
  198. arg0.type = GRPC_ARG_STRING;
  199. arg0.key = const_cast<char*>(GRPC_ARG_PRIMARY_USER_AGENT_STRING);
  200. arg0.value.string = const_cast<char*>(whole_prefix.c_str());
  201. channel_args_.SetUserAgentPrefix(prefix);
  202. EXPECT_TRUE(HasArg(arg0));
  203. // Test if the user agent string is copied correctly
  204. ChannelArguments new_channel_args(channel_args_);
  205. grpc_channel_args args;
  206. SetChannelArgs(new_channel_args, &args);
  207. bool found = false;
  208. for (size_t i = 0; i < args.num_args; i++) {
  209. const grpc_arg& arg = args.args[i];
  210. if (arg.type == GRPC_ARG_STRING &&
  211. std::string(arg.key) == GRPC_ARG_PRIMARY_USER_AGENT_STRING) {
  212. EXPECT_FALSE(found);
  213. EXPECT_EQ(0, strcmp(arg.value.string, arg0.value.string));
  214. found = true;
  215. }
  216. }
  217. EXPECT_TRUE(found);
  218. }
  219. } // namespace testing
  220. } // namespace grpc
  221. int main(int argc, char** argv) {
  222. grpc::testing::TestEnvironment env(argc, argv);
  223. ::testing::InitGoogleTest(&argc, argv);
  224. int ret = RUN_ALL_TESTS();
  225. return ret;
  226. }