• 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 * 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 * elem)49 static void channel_destroy_func(grpc_channel_element* elem) {}
50 
call_destroy_func(grpc_call_element * elem,const grpc_call_final_info * final_info,grpc_closure * ignored)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 * op)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 * op)62 static void channel_func(grpc_channel_element* elem, grpc_transport_op* op) {
63   ++*static_cast<int*>(elem->channel_data);
64 }
65 
free_channel(void * arg,grpc_error * error)66 static void free_channel(void* arg, grpc_error* error) {
67   grpc_channel_stack_destroy(static_cast<grpc_channel_stack*>(arg));
68   gpr_free(arg);
69 }
70 
free_call(void * arg,grpc_error * error)71 static void free_call(void* arg, grpc_error* error) {
72   grpc_call_stack_destroy(static_cast<grpc_call_stack*>(arg), nullptr, nullptr);
73   gpr_free(arg);
74 }
75 
test_create_channel_stack(void)76 static void test_create_channel_stack(void) {
77   const grpc_channel_filter filter = {
78       call_func,
79       channel_func,
80       sizeof(int),
81       call_init_func,
82       grpc_call_stack_ignore_set_pollset_or_pollset_set,
83       call_destroy_func,
84       sizeof(int),
85       channel_init_func,
86       channel_destroy_func,
87       grpc_channel_next_get_info,
88       "some_test_filter"};
89   const grpc_channel_filter* filters = &filter;
90   grpc_channel_stack* channel_stack;
91   grpc_call_stack* call_stack;
92   grpc_channel_element* channel_elem;
93   grpc_call_element* call_elem;
94   grpc_arg arg;
95   grpc_channel_args chan_args;
96   int* channel_data;
97   int* call_data;
98   grpc_core::ExecCtx exec_ctx;
99   grpc_slice path = grpc_slice_from_static_string("/service/method");
100 
101   arg.type = GRPC_ARG_INTEGER;
102   arg.key = const_cast<char*>("test_key");
103   arg.value.integer = 42;
104 
105   chan_args.num_args = 1;
106   chan_args.args = &arg;
107 
108   channel_stack = static_cast<grpc_channel_stack*>(
109       gpr_malloc(grpc_channel_stack_size(&filters, 1)));
110   grpc_channel_stack_init(1, free_channel, channel_stack, &filters, 1,
111                           &chan_args, nullptr, "test", channel_stack);
112   GPR_ASSERT(channel_stack->count == 1);
113   channel_elem = grpc_channel_stack_element(channel_stack, 0);
114   channel_data = static_cast<int*>(channel_elem->channel_data);
115   GPR_ASSERT(*channel_data == 0);
116 
117   call_stack =
118       static_cast<grpc_call_stack*>(gpr_malloc(channel_stack->call_stack_size));
119   const grpc_call_element_args args = {
120       call_stack,                   /* call_stack */
121       nullptr,                      /* server_transport_data */
122       nullptr,                      /* context */
123       path,                         /* path */
124       gpr_now(GPR_CLOCK_MONOTONIC), /* start_time */
125       GRPC_MILLIS_INF_FUTURE,       /* deadline */
126       nullptr,                      /* arena */
127       nullptr,                      /* call_combiner */
128   };
129   grpc_error* error =
130       grpc_call_stack_init(channel_stack, 1, free_call, call_stack, &args);
131   GPR_ASSERT(error == GRPC_ERROR_NONE);
132   GPR_ASSERT(call_stack->count == 1);
133   call_elem = grpc_call_stack_element(call_stack, 0);
134   GPR_ASSERT(call_elem->filter == channel_elem->filter);
135   GPR_ASSERT(call_elem->channel_data == channel_elem->channel_data);
136   call_data = static_cast<int*>(call_elem->call_data);
137   GPR_ASSERT(*call_data == 0);
138   GPR_ASSERT(*channel_data == 1);
139 
140   GRPC_CALL_STACK_UNREF(call_stack, "done");
141   grpc_core::ExecCtx::Get()->Flush();
142   GPR_ASSERT(*channel_data == 2);
143 
144   GRPC_CHANNEL_STACK_UNREF(channel_stack, "done");
145 
146   grpc_slice_unref_internal(path);
147 }
148 
main(int argc,char ** argv)149 int main(int argc, char** argv) {
150   grpc_test_init(argc, argv);
151   grpc_init();
152   test_create_channel_stack();
153   grpc_shutdown();
154   return 0;
155 }
156