• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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 
19 #include <string.h>
20 
21 #include <grpc/support/log.h>
22 
23 #include "src/core/lib/channel/channel_args.h"
24 #include "src/core/lib/gpr/useful.h"
25 #include "src/core/lib/iomgr/exec_ctx.h"
26 #include "test/core/util/test_config.h"
27 
test_create(void)28 static void test_create(void) {
29   grpc_core::ExecCtx exec_ctx;
30 
31   grpc_arg arg_int;
32   grpc_arg arg_string;
33   grpc_arg to_add[2];
34   grpc_channel_args* ch_args;
35 
36   arg_int.key = const_cast<char*>("int_arg");
37   arg_int.type = GRPC_ARG_INTEGER;
38   arg_int.value.integer = 123;
39 
40   arg_string.key = const_cast<char*>("str key");
41   arg_string.type = GRPC_ARG_STRING;
42   arg_string.value.string = const_cast<char*>("str value");
43 
44   to_add[0] = arg_int;
45   to_add[1] = arg_string;
46   ch_args = grpc_channel_args_copy_and_add(nullptr, to_add, 2);
47 
48   GPR_ASSERT(ch_args->num_args == 2);
49   GPR_ASSERT(strcmp(ch_args->args[0].key, arg_int.key) == 0);
50   GPR_ASSERT(ch_args->args[0].type == arg_int.type);
51   GPR_ASSERT(ch_args->args[0].value.integer == arg_int.value.integer);
52 
53   GPR_ASSERT(strcmp(ch_args->args[1].key, arg_string.key) == 0);
54   GPR_ASSERT(ch_args->args[1].type == arg_string.type);
55   GPR_ASSERT(strcmp(ch_args->args[1].value.string, arg_string.value.string) ==
56              0);
57 
58   grpc_channel_args_destroy(ch_args);
59 }
60 
test_set_compression_algorithm(void)61 static void test_set_compression_algorithm(void) {
62   grpc_core::ExecCtx exec_ctx;
63   grpc_channel_args* ch_args;
64 
65   ch_args =
66       grpc_channel_args_set_compression_algorithm(nullptr, GRPC_COMPRESS_GZIP);
67   GPR_ASSERT(ch_args->num_args == 1);
68   GPR_ASSERT(strcmp(ch_args->args[0].key,
69                     GRPC_COMPRESSION_CHANNEL_DEFAULT_ALGORITHM) == 0);
70   GPR_ASSERT(ch_args->args[0].type == GRPC_ARG_INTEGER);
71 
72   grpc_channel_args_destroy(ch_args);
73 }
74 
test_compression_algorithm_states(void)75 static void test_compression_algorithm_states(void) {
76   grpc_core::ExecCtx exec_ctx;
77   grpc_channel_args *ch_args, *ch_args_wo_gzip, *ch_args_wo_gzip_deflate,
78       *ch_args_wo_gzip_deflate_gzip;
79   unsigned states_bitset;
80   size_t i;
81 
82   ch_args = grpc_channel_args_copy_and_add(nullptr, nullptr, 0);
83   /* by default, all enabled */
84   states_bitset = static_cast<unsigned>(
85       grpc_channel_args_compression_algorithm_get_states(ch_args));
86 
87   for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) {
88     GPR_ASSERT(GPR_BITGET(states_bitset, i));
89   }
90 
91   /* disable gzip and deflate and stream/gzip */
92   ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state(
93       &ch_args, GRPC_COMPRESS_GZIP, 0);
94   GPR_ASSERT(ch_args == ch_args_wo_gzip);
95   ch_args_wo_gzip_deflate = grpc_channel_args_compression_algorithm_set_state(
96       &ch_args_wo_gzip, GRPC_COMPRESS_DEFLATE, 0);
97   GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate);
98   ch_args_wo_gzip_deflate_gzip =
99       grpc_channel_args_compression_algorithm_set_state(
100           &ch_args_wo_gzip_deflate, GRPC_COMPRESS_STREAM_GZIP, 0);
101   GPR_ASSERT(ch_args_wo_gzip_deflate == ch_args_wo_gzip_deflate_gzip);
102 
103   states_bitset =
104       static_cast<unsigned>(grpc_channel_args_compression_algorithm_get_states(
105           ch_args_wo_gzip_deflate));
106   for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) {
107     if (i == GRPC_COMPRESS_GZIP || i == GRPC_COMPRESS_DEFLATE ||
108         i == GRPC_COMPRESS_STREAM_GZIP) {
109       GPR_ASSERT(GPR_BITGET(states_bitset, i) == 0);
110     } else {
111       GPR_ASSERT(GPR_BITGET(states_bitset, i) != 0);
112     }
113   }
114 
115   /* re-enabled gzip and stream/gzip only */
116   ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state(
117       &ch_args_wo_gzip_deflate_gzip, GRPC_COMPRESS_GZIP, 1);
118   ch_args_wo_gzip = grpc_channel_args_compression_algorithm_set_state(
119       &ch_args_wo_gzip, GRPC_COMPRESS_STREAM_GZIP, 1);
120   GPR_ASSERT(ch_args_wo_gzip == ch_args_wo_gzip_deflate_gzip);
121 
122   states_bitset = static_cast<unsigned>(
123       grpc_channel_args_compression_algorithm_get_states(ch_args_wo_gzip));
124   for (i = 0; i < GRPC_COMPRESS_ALGORITHMS_COUNT; i++) {
125     if (i == GRPC_COMPRESS_DEFLATE) {
126       GPR_ASSERT(GPR_BITGET(states_bitset, i) == 0);
127     } else {
128       GPR_ASSERT(GPR_BITGET(states_bitset, i) != 0);
129     }
130   }
131 
132   grpc_channel_args_destroy(ch_args);
133 }
134 
test_set_socket_mutator(void)135 static void test_set_socket_mutator(void) {
136   grpc_channel_args* ch_args;
137   grpc_socket_mutator mutator;
138   grpc_socket_mutator_init(&mutator, nullptr);
139 
140   ch_args = grpc_channel_args_set_socket_mutator(nullptr, &mutator);
141   GPR_ASSERT(ch_args->num_args == 1);
142   GPR_ASSERT(strcmp(ch_args->args[0].key, GRPC_ARG_SOCKET_MUTATOR) == 0);
143   GPR_ASSERT(ch_args->args[0].type == GRPC_ARG_POINTER);
144 
145   {
146     grpc_core::ExecCtx exec_ctx;
147     grpc_channel_args_destroy(ch_args);
148   }
149 }
150 
151 struct fake_class {
152   int foo;
153 };
154 
fake_pointer_arg_copy(void * arg)155 static void* fake_pointer_arg_copy(void* arg) {
156   gpr_log(GPR_DEBUG, "fake_pointer_arg_copy");
157   fake_class* fc = static_cast<fake_class*>(arg);
158   fake_class* new_fc = static_cast<fake_class*>(gpr_malloc(sizeof(fake_class)));
159   new_fc->foo = fc->foo;
160   return new_fc;
161 }
162 
fake_pointer_arg_destroy(void * arg)163 static void fake_pointer_arg_destroy(void* arg) {
164   gpr_log(GPR_DEBUG, "fake_pointer_arg_destroy");
165   fake_class* fc = static_cast<fake_class*>(arg);
166   gpr_free(fc);
167 }
168 
fake_pointer_cmp(void * a,void * b)169 static int fake_pointer_cmp(void* a, void* b) { return GPR_ICMP(a, b); }
170 
171 static const grpc_arg_pointer_vtable fake_pointer_arg_vtable = {
172     fake_pointer_arg_copy, fake_pointer_arg_destroy, fake_pointer_cmp};
173 
test_channel_create_with_args(void)174 static void test_channel_create_with_args(void) {
175   grpc_arg client_a[3];
176 
177   // adds integer arg
178   client_a[0].type = GRPC_ARG_INTEGER;
179   client_a[0].key = const_cast<char*>("arg_int");
180   client_a[0].value.integer = 0;
181 
182   // adds const str arg
183   client_a[1].type = GRPC_ARG_STRING;
184   client_a[1].key = const_cast<char*>("arg_str");
185   client_a[1].value.string = const_cast<char*>("arg_str_val");
186 
187   // allocated and adds custom pointer arg
188   fake_class* fc = static_cast<fake_class*>(gpr_malloc(sizeof(fake_class)));
189   fc->foo = 42;
190   client_a[2].type = GRPC_ARG_POINTER;
191   client_a[2].key = const_cast<char*>("arg_pointer");
192   client_a[2].value.pointer.vtable = &fake_pointer_arg_vtable;
193   client_a[2].value.pointer.p = fc;
194 
195   // creates channel
196   grpc_channel_args client_args = {GPR_ARRAY_SIZE(client_a), client_a};
197   grpc_channel* c =
198       grpc_insecure_channel_create("fake_target", &client_args, nullptr);
199   // user is can free the memory they allocated here
200   gpr_free(fc);
201   grpc_channel_destroy(c);
202 }
203 
test_server_create_with_args(void)204 static void test_server_create_with_args(void) {
205   grpc_arg server_a[3];
206 
207   // adds integer arg
208   server_a[0].type = GRPC_ARG_INTEGER;
209   server_a[0].key = const_cast<char*>("arg_int");
210   server_a[0].value.integer = 0;
211 
212   // adds const str arg
213   server_a[1].type = GRPC_ARG_STRING;
214   server_a[1].key = const_cast<char*>("arg_str");
215   server_a[1].value.string = const_cast<char*>("arg_str_val");
216 
217   // allocated and adds custom pointer arg
218   fake_class* fc = static_cast<fake_class*>(gpr_malloc(sizeof(fake_class)));
219   fc->foo = 42;
220   server_a[2].type = GRPC_ARG_POINTER;
221   server_a[2].key = const_cast<char*>("arg_pointer");
222   server_a[2].value.pointer.vtable = &fake_pointer_arg_vtable;
223   server_a[2].value.pointer.p = fc;
224 
225   // creates server
226   grpc_channel_args server_args = {GPR_ARRAY_SIZE(server_a), server_a};
227   grpc_server* s = grpc_server_create(&server_args, nullptr);
228   // user is can free the memory they allocated here
229   gpr_free(fc);
230   grpc_server_destroy(s);
231 }
232 
main(int argc,char ** argv)233 int main(int argc, char** argv) {
234   grpc_test_init(argc, argv);
235   grpc_init();
236   test_create();
237   test_set_compression_algorithm();
238   test_compression_algorithm_states();
239   test_set_socket_mutator();
240   test_channel_create_with_args();
241   test_server_create_with_args();
242   grpc_shutdown();
243   return 0;
244 }
245