1 /* 2 * 3 * Copyright 2016 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/grpc.h> 22 #include <grpc/support/alloc.h> 23 #include <grpc/support/log.h> 24 #include <grpc/support/string_util.h> 25 26 #include "src/core/lib/channel/channel_args.h" 27 #include "src/core/lib/gpr/host_port.h" 28 #include "src/core/lib/iomgr/exec_ctx.h" 29 #include "src/core/lib/slice/slice_internal.h" 30 #include "src/core/lib/transport/metadata.h" 31 #include "src/core/lib/transport/service_config.h" 32 33 #include "test/core/end2end/cq_verifier.h" 34 #include "test/core/util/port.h" 35 #include "test/core/util/test_config.h" 36 37 static void* tag(intptr_t i) { return (void*)i; } 38 39 static void run_test(bool wait_for_ready, bool use_service_config) { 40 grpc_channel* chan; 41 grpc_call* call; 42 grpc_completion_queue* cq; 43 cq_verifier* cqv; 44 grpc_op ops[6]; 45 grpc_op* op; 46 grpc_metadata_array trailing_metadata_recv; 47 grpc_status_code status; 48 grpc_slice details; 49 50 gpr_log(GPR_INFO, "TEST: wait_for_ready=%d use_service_config=%d", 51 wait_for_ready, use_service_config); 52 53 grpc_init(); 54 55 grpc_metadata_array_init(&trailing_metadata_recv); 56 57 cq = grpc_completion_queue_create_for_next(nullptr); 58 cqv = cq_verifier_create(cq); 59 60 /* if using service config, create channel args */ 61 grpc_channel_args* args = nullptr; 62 if (use_service_config) { 63 GPR_ASSERT(wait_for_ready); 64 grpc_arg arg; 65 arg.type = GRPC_ARG_STRING; 66 arg.key = const_cast<char*>(GRPC_ARG_SERVICE_CONFIG); 67 arg.value.string = const_cast<char*>( 68 "{\n" 69 " \"methodConfig\": [ {\n" 70 " \"name\": [\n" 71 " { \"service\": \"service\", \"method\": \"method\" }\n" 72 " ],\n" 73 " \"waitForReady\": true\n" 74 " } ]\n" 75 "}"); 76 args = grpc_channel_args_copy_and_add(args, &arg, 1); 77 } 78 79 /* create a call, channel to a port which will refuse connection */ 80 int port = grpc_pick_unused_port_or_die(); 81 char* addr; 82 gpr_join_host_port(&addr, "127.0.0.1", port); 83 gpr_log(GPR_INFO, "server: %s", addr); 84 chan = grpc_insecure_channel_create(addr, args, nullptr); 85 grpc_slice host = grpc_slice_from_static_string("nonexistant"); 86 gpr_timespec deadline = grpc_timeout_seconds_to_deadline(2); 87 call = 88 grpc_channel_create_call(chan, nullptr, GRPC_PROPAGATE_DEFAULTS, cq, 89 grpc_slice_from_static_string("/service/method"), 90 &host, deadline, nullptr); 91 92 gpr_free(addr); 93 94 memset(ops, 0, sizeof(ops)); 95 op = ops; 96 op->op = GRPC_OP_SEND_INITIAL_METADATA; 97 op->data.send_initial_metadata.count = 0; 98 op->flags = (wait_for_ready && !use_service_config) 99 ? GRPC_INITIAL_METADATA_WAIT_FOR_READY 100 : 0; 101 op->reserved = nullptr; 102 op++; 103 op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; 104 op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; 105 op->data.recv_status_on_client.status = &status; 106 op->data.recv_status_on_client.status_details = &details; 107 op->flags = 0; 108 op->reserved = nullptr; 109 op++; 110 GPR_ASSERT(GRPC_CALL_OK == grpc_call_start_batch(call, ops, 111 (size_t)(op - ops), tag(1), 112 nullptr)); 113 /* verify that all tags get completed */ 114 CQ_EXPECT_COMPLETION(cqv, tag(1), 1); 115 cq_verify(cqv); 116 117 if (wait_for_ready) { 118 GPR_ASSERT(status == GRPC_STATUS_DEADLINE_EXCEEDED); 119 } else { 120 GPR_ASSERT(status == GRPC_STATUS_UNAVAILABLE); 121 } 122 123 grpc_completion_queue_shutdown(cq); 124 while (grpc_completion_queue_next(cq, gpr_inf_future(GPR_CLOCK_REALTIME), 125 nullptr) 126 .type != GRPC_QUEUE_SHUTDOWN) 127 ; 128 grpc_completion_queue_destroy(cq); 129 grpc_call_unref(call); 130 grpc_channel_destroy(chan); 131 cq_verifier_destroy(cqv); 132 133 grpc_slice_unref(details); 134 grpc_metadata_array_destroy(&trailing_metadata_recv); 135 136 { 137 grpc_core::ExecCtx exec_ctx; 138 if (args != nullptr) grpc_channel_args_destroy(args); 139 } 140 141 grpc_shutdown(); 142 } 143 144 int main(int argc, char** argv) { 145 grpc_test_init(argc, argv); 146 run_test(false /* wait_for_ready */, false /* use_service_config */); 147 run_test(true /* wait_for_ready */, false /* use_service_config */); 148 run_test(true /* wait_for_ready */, true /* use_service_config */); 149 return 0; 150 } 151