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 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 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 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 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 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 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 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 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 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 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