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