Home | History | Annotate | Download | only in channel
      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