| /* |
| * |
| * Copyright 2015 gRPC authors. |
| * |
| * Licensed under the Apache License, Version 2.0 (the "License"); |
| * you may not use this file except in compliance with the License. |
| * You may obtain a copy of the License at |
| * |
| * http://www.apache.org/licenses/LICENSE-2.0 |
| * |
| * Unless required by applicable law or agreed to in writing, software |
| * distributed under the License is distributed on an "AS IS" BASIS, |
| * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
| * See the License for the specific language governing permissions and |
| * limitations under the License. |
| * |
| */ |
| |
| #include "src/core/lib/channel/channel_stack.h" |
| |
| #include <string.h> |
| |
| #include <grpc/support/alloc.h> |
| #include <grpc/support/log.h> |
| #include <grpc/support/string_util.h> |
| |
| #include "src/core/lib/slice/slice_internal.h" |
| #include "test/core/util/test_config.h" |
| |
| static grpc_error *channel_init_func(grpc_exec_ctx *exec_ctx, |
| grpc_channel_element *elem, |
| grpc_channel_element_args *args) { |
| GPR_ASSERT(args->channel_args->num_args == 1); |
| GPR_ASSERT(args->channel_args->args[0].type == GRPC_ARG_INTEGER); |
| GPR_ASSERT(0 == strcmp(args->channel_args->args[0].key, "test_key")); |
| GPR_ASSERT(args->channel_args->args[0].value.integer == 42); |
| GPR_ASSERT(args->is_first); |
| GPR_ASSERT(args->is_last); |
| *(int *)(elem->channel_data) = 0; |
| return GRPC_ERROR_NONE; |
| } |
| |
| static grpc_error *call_init_func(grpc_exec_ctx *exec_ctx, |
| grpc_call_element *elem, |
| const grpc_call_element_args *args) { |
| ++*(int *)(elem->channel_data); |
| *(int *)(elem->call_data) = 0; |
| return GRPC_ERROR_NONE; |
| } |
| |
| static void channel_destroy_func(grpc_exec_ctx *exec_ctx, |
| grpc_channel_element *elem) {} |
| |
| static void call_destroy_func(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, |
| const grpc_call_final_info *final_info, |
| grpc_closure *ignored) { |
| ++*(int *)(elem->channel_data); |
| } |
| |
| static void call_func(grpc_exec_ctx *exec_ctx, grpc_call_element *elem, |
| grpc_transport_stream_op_batch *op) { |
| ++*(int *)(elem->call_data); |
| } |
| |
| static void channel_func(grpc_exec_ctx *exec_ctx, grpc_channel_element *elem, |
| grpc_transport_op *op) { |
| ++*(int *)(elem->channel_data); |
| } |
| |
| static void free_channel(grpc_exec_ctx *exec_ctx, void *arg, |
| grpc_error *error) { |
| grpc_channel_stack_destroy(exec_ctx, arg); |
| gpr_free(arg); |
| } |
| |
| static void free_call(grpc_exec_ctx *exec_ctx, void *arg, grpc_error *error) { |
| grpc_call_stack_destroy(exec_ctx, arg, NULL, NULL); |
| gpr_free(arg); |
| } |
| |
| static void test_create_channel_stack(void) { |
| const grpc_channel_filter filter = { |
| call_func, |
| channel_func, |
| sizeof(int), |
| call_init_func, |
| grpc_call_stack_ignore_set_pollset_or_pollset_set, |
| call_destroy_func, |
| sizeof(int), |
| channel_init_func, |
| channel_destroy_func, |
| grpc_channel_next_get_info, |
| "some_test_filter"}; |
| const grpc_channel_filter *filters = &filter; |
| grpc_channel_stack *channel_stack; |
| grpc_call_stack *call_stack; |
| grpc_channel_element *channel_elem; |
| grpc_call_element *call_elem; |
| grpc_arg arg; |
| grpc_channel_args chan_args; |
| int *channel_data; |
| int *call_data; |
| grpc_exec_ctx exec_ctx = GRPC_EXEC_CTX_INIT; |
| grpc_slice path = grpc_slice_from_static_string("/service/method"); |
| |
| arg.type = GRPC_ARG_INTEGER; |
| arg.key = "test_key"; |
| arg.value.integer = 42; |
| |
| chan_args.num_args = 1; |
| chan_args.args = &arg; |
| |
| channel_stack = gpr_malloc(grpc_channel_stack_size(&filters, 1)); |
| grpc_channel_stack_init(&exec_ctx, 1, free_channel, channel_stack, &filters, |
| 1, &chan_args, NULL, "test", channel_stack); |
| GPR_ASSERT(channel_stack->count == 1); |
| channel_elem = grpc_channel_stack_element(channel_stack, 0); |
| channel_data = (int *)channel_elem->channel_data; |
| GPR_ASSERT(*channel_data == 0); |
| |
| call_stack = gpr_malloc(channel_stack->call_stack_size); |
| const grpc_call_element_args args = { |
| .call_stack = call_stack, |
| .server_transport_data = NULL, |
| .context = NULL, |
| .path = path, |
| .start_time = gpr_now(GPR_CLOCK_MONOTONIC), |
| .deadline = GRPC_MILLIS_INF_FUTURE, |
| .arena = NULL}; |
| grpc_error *error = grpc_call_stack_init(&exec_ctx, channel_stack, 1, |
| free_call, call_stack, &args); |
| GPR_ASSERT(error == GRPC_ERROR_NONE); |
| GPR_ASSERT(call_stack->count == 1); |
| call_elem = grpc_call_stack_element(call_stack, 0); |
| GPR_ASSERT(call_elem->filter == channel_elem->filter); |
| GPR_ASSERT(call_elem->channel_data == channel_elem->channel_data); |
| call_data = (int *)call_elem->call_data; |
| GPR_ASSERT(*call_data == 0); |
| GPR_ASSERT(*channel_data == 1); |
| |
| GRPC_CALL_STACK_UNREF(&exec_ctx, call_stack, "done"); |
| grpc_exec_ctx_flush(&exec_ctx); |
| GPR_ASSERT(*channel_data == 2); |
| |
| GRPC_CHANNEL_STACK_UNREF(&exec_ctx, channel_stack, "done"); |
| |
| grpc_slice_unref_internal(&exec_ctx, path); |
| grpc_exec_ctx_finish(&exec_ctx); |
| } |
| |
| int main(int argc, char **argv) { |
| grpc_test_init(argc, argv); |
| grpc_init(); |
| test_create_channel_stack(); |
| grpc_shutdown(); |
| return 0; |
| } |