• 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 "src/core/lib/channel/channel_stack.h"
20 
21 #include <string.h>
22 
23 #include <grpc/support/alloc.h>
24 #include <grpc/support/log.h>
25 #include <grpc/support/string_util.h>
26 
27 #include "src/core/lib/slice/slice_internal.h"
28 #include "test/core/util/test_config.h"
29 
channel_init_func(grpc_channel_element * elem,grpc_channel_element_args * args)30 static grpc_error* channel_init_func(grpc_channel_element* elem,
31                                      grpc_channel_element_args* args) {
32   GPR_ASSERT(args->channel_args->num_args == 1);
33   GPR_ASSERT(args->channel_args->args[0].type == GRPC_ARG_INTEGER);
34   GPR_ASSERT(0 == strcmp(args->channel_args->args[0].key, "test_key"));
35   GPR_ASSERT(args->channel_args->args[0].value.integer == 42);
36   GPR_ASSERT(args->is_first);
37   GPR_ASSERT(args->is_last);
38   *static_cast<int*>(elem->channel_data) = 0;
39   return GRPC_ERROR_NONE;
40 }
41 
call_init_func(grpc_call_element * elem,const grpc_call_element_args *)42 static grpc_error* call_init_func(grpc_call_element* elem,
43                                   const grpc_call_element_args* /*args*/) {
44   ++*static_cast<int*>(elem->channel_data);
45   *static_cast<int*>(elem->call_data) = 0;
46   return GRPC_ERROR_NONE;
47 }
48 
channel_destroy_func(grpc_channel_element *)49 static void channel_destroy_func(grpc_channel_element* /*elem*/) {}
50 
call_destroy_func(grpc_call_element * elem,const grpc_call_final_info *,grpc_closure *)51 static void call_destroy_func(grpc_call_element* elem,
52                               const grpc_call_final_info* /*final_info*/,
53                               grpc_closure* /*ignored*/) {
54   ++*static_cast<int*>(elem->channel_data);
55 }
56 
call_func(grpc_call_element * elem,grpc_transport_stream_op_batch *)57 static void call_func(grpc_call_element* elem,
58                       grpc_transport_stream_op_batch* /*op*/) {
59   ++*static_cast<int*>(elem->call_data);
60 }
61 
channel_func(grpc_channel_element * elem,grpc_transport_op *)62 static void channel_func(grpc_channel_element* elem,
63                          grpc_transport_op* /*op*/) {
64   ++*static_cast<int*>(elem->channel_data);
65 }
66 
free_channel(void * arg,grpc_error *)67 static void free_channel(void* arg, grpc_error* /*error*/) {
68   grpc_channel_stack_destroy(static_cast<grpc_channel_stack*>(arg));
69   gpr_free(arg);
70 }
71 
free_call(void * arg,grpc_error *)72 static void free_call(void* arg, grpc_error* /*error*/) {
73   grpc_call_stack_destroy(static_cast<grpc_call_stack*>(arg), nullptr, nullptr);
74   gpr_free(arg);
75 }
76 
test_create_channel_stack(void)77 static void test_create_channel_stack(void) {
78   const grpc_channel_filter filter = {
79       call_func,
80       channel_func,
81       sizeof(int),
82       call_init_func,
83       grpc_call_stack_ignore_set_pollset_or_pollset_set,
84       call_destroy_func,
85       sizeof(int),
86       channel_init_func,
87       channel_destroy_func,
88       grpc_channel_next_get_info,
89       "some_test_filter"};
90   const grpc_channel_filter* filters = &filter;
91   grpc_channel_stack* channel_stack;
92   grpc_call_stack* call_stack;
93   grpc_channel_element* channel_elem;
94   grpc_call_element* call_elem;
95   grpc_arg arg;
96   grpc_channel_args chan_args;
97   int* channel_data;
98   int* call_data;
99   grpc_core::ExecCtx exec_ctx;
100   grpc_slice path = grpc_slice_from_static_string("/service/method");
101 
102   arg.type = GRPC_ARG_INTEGER;
103   arg.key = const_cast<char*>("test_key");
104   arg.value.integer = 42;
105 
106   chan_args.num_args = 1;
107   chan_args.args = &arg;
108 
109   channel_stack = static_cast<grpc_channel_stack*>(
110       gpr_malloc(grpc_channel_stack_size(&filters, 1)));
111   grpc_channel_stack_init(1, free_channel, channel_stack, &filters, 1,
112                           &chan_args, nullptr, "test", channel_stack);
113   GPR_ASSERT(channel_stack->count == 1);
114   channel_elem = grpc_channel_stack_element(channel_stack, 0);
115   channel_data = static_cast<int*>(channel_elem->channel_data);
116   GPR_ASSERT(*channel_data == 0);
117 
118   call_stack =
119       static_cast<grpc_call_stack*>(gpr_malloc(channel_stack->call_stack_size));
120   const grpc_call_element_args args = {
121       call_stack,              /* call_stack */
122       nullptr,                 /* server_transport_data */
123       nullptr,                 /* context */
124       path,                    /* path */
125       gpr_get_cycle_counter(), /* start_time */
126       GRPC_MILLIS_INF_FUTURE,  /* deadline */
127       nullptr,                 /* arena */
128       nullptr,                 /* call_combiner */
129   };
130   grpc_error* error =
131       grpc_call_stack_init(channel_stack, 1, free_call, call_stack, &args);
132   GPR_ASSERT(error == GRPC_ERROR_NONE);
133   GPR_ASSERT(call_stack->count == 1);
134   call_elem = grpc_call_stack_element(call_stack, 0);
135   GPR_ASSERT(call_elem->filter == channel_elem->filter);
136   GPR_ASSERT(call_elem->channel_data == channel_elem->channel_data);
137   call_data = static_cast<int*>(call_elem->call_data);
138   GPR_ASSERT(*call_data == 0);
139   GPR_ASSERT(*channel_data == 1);
140 
141   GRPC_CALL_STACK_UNREF(call_stack, "done");
142   grpc_core::ExecCtx::Get()->Flush();
143   GPR_ASSERT(*channel_data == 2);
144 
145   GRPC_CHANNEL_STACK_UNREF(channel_stack, "done");
146 
147   grpc_slice_unref_internal(path);
148 }
149 
main(int argc,char ** argv)150 int main(int argc, char** argv) {
151   grpc::testing::TestEnvironment env(argc, argv);
152   grpc_init();
153   test_create_channel_stack();
154   grpc_shutdown();
155   return 0;
156 }
157