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 "test/core/end2end/end2end_tests.h" 20 21 #include <stdio.h> 22 #include <string.h> 23 24 #include <grpc/byte_buffer.h> 25 #include <grpc/grpc.h> 26 #include <grpc/support/alloc.h> 27 #include <grpc/support/log.h> 28 #include <grpc/support/time.h> 29 #include "src/core/lib/debug/stats.h" 30 #include "src/core/lib/gpr/string.h" 31 #include "test/core/end2end/cq_verifier.h" 32 33 static void* tag(intptr_t t) { return (void*)t; } 34 35 static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config, 36 const char* test_name, 37 grpc_channel_args* client_args, 38 grpc_channel_args* server_args) { 39 grpc_end2end_test_fixture f; 40 gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name); 41 f = config.create_fixture(client_args, server_args); 42 config.init_server(&f, server_args); 43 config.init_client(&f, client_args); 44 return f; 45 } 46 47 static gpr_timespec n_seconds_from_now(int n) { 48 return grpc_timeout_seconds_to_deadline(n); 49 } 50 51 static gpr_timespec five_seconds_from_now(void) { 52 return n_seconds_from_now(5); 53 } 54 55 static void drain_cq(grpc_completion_queue* cq) { 56 grpc_event ev; 57 do { 58 ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr); 59 } while (ev.type != GRPC_QUEUE_SHUTDOWN); 60 } 61 62 static void shutdown_server(grpc_end2end_test_fixture* f) { 63 if (!f->server) return; 64 grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000)); 65 GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000), 66 grpc_timeout_seconds_to_deadline(5), 67 nullptr) 68 .type == GRPC_OP_COMPLETE); 69 grpc_server_destroy(f->server); 70 f->server = nullptr; 71 } 72 73 static void shutdown_client(grpc_end2end_test_fixture* f) { 74 if (!f->client) return; 75 grpc_channel_destroy(f->client); 76 f->client = nullptr; 77 } 78 79 static void end_test(grpc_end2end_test_fixture* f) { 80 shutdown_server(f); 81 shutdown_client(f); 82 83 grpc_completion_queue_shutdown(f->cq); 84 drain_cq(f->cq); 85 grpc_completion_queue_destroy(f->cq); 86 grpc_completion_queue_destroy(f->shutdown_cq); 87 } 88 89 static void simple_request_body(grpc_end2end_test_config config, 90 grpc_end2end_test_fixture f) { 91 grpc_call* c; 92 grpc_call* s; 93 cq_verifier* cqv = cq_verifier_create(f.cq); 94 grpc_op ops[6]; 95 grpc_op* op; 96 grpc_metadata_array initial_metadata_recv; 97 grpc_metadata_array trailing_metadata_recv; 98 grpc_metadata_array request_metadata_recv; 99 grpc_call_details call_details; 100 grpc_status_code status; 101 const char* error_string; 102 grpc_call_error error; 103 grpc_slice details; 104 int was_cancelled = 2; 105 char* peer; 106 grpc_stats_data* before = 107 static_cast<grpc_stats_data*>(gpr_malloc(sizeof(grpc_stats_data))); 108 grpc_stats_data* after = 109 static_cast<grpc_stats_data*>(gpr_malloc(sizeof(grpc_stats_data))); 110 111 grpc_stats_collect(before); 112 113 gpr_timespec deadline = five_seconds_from_now(); 114 c = grpc_channel_create_call(f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq, 115 grpc_slice_from_static_string("/foo"), nullptr, 116 deadline, nullptr); 117 GPR_ASSERT(c); 118 119 peer = grpc_call_get_peer(c); 120 GPR_ASSERT(peer != nullptr); 121 gpr_log(GPR_DEBUG, "client_peer_before_call=%s", peer); 122 gpr_free(peer); 123 124 grpc_metadata_array_init(&initial_metadata_recv); 125 grpc_metadata_array_init(&trailing_metadata_recv); 126 grpc_metadata_array_init(&request_metadata_recv); 127 grpc_call_details_init(&call_details); 128 129 memset(ops, 0, sizeof(ops)); 130 op = ops; 131 op->op = GRPC_OP_SEND_INITIAL_METADATA; 132 op->data.send_initial_metadata.count = 0; 133 op->flags = 0; 134 op->reserved = nullptr; 135 op++; 136 op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT; 137 op->flags = 0; 138 op->reserved = nullptr; 139 op++; 140 op->op = GRPC_OP_RECV_INITIAL_METADATA; 141 op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv; 142 op->flags = 0; 143 op->reserved = nullptr; 144 op++; 145 op->op = GRPC_OP_RECV_STATUS_ON_CLIENT; 146 op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv; 147 op->data.recv_status_on_client.status = &status; 148 op->data.recv_status_on_client.status_details = &details; 149 op->data.recv_status_on_client.error_string = &error_string; 150 op->flags = 0; 151 op->reserved = nullptr; 152 op++; 153 error = grpc_call_start_batch(c, ops, static_cast<size_t>(op - ops), tag(1), 154 nullptr); 155 GPR_ASSERT(GRPC_CALL_OK == error); 156 157 error = 158 grpc_server_request_call(f.server, &s, &call_details, 159 &request_metadata_recv, f.cq, f.cq, tag(101)); 160 GPR_ASSERT(GRPC_CALL_OK == error); 161 CQ_EXPECT_COMPLETION(cqv, tag(101), 1); 162 cq_verify(cqv); 163 164 peer = grpc_call_get_peer(s); 165 GPR_ASSERT(peer != nullptr); 166 gpr_log(GPR_DEBUG, "server_peer=%s", peer); 167 gpr_free(peer); 168 peer = grpc_call_get_peer(c); 169 GPR_ASSERT(peer != nullptr); 170 gpr_log(GPR_DEBUG, "client_peer=%s", peer); 171 gpr_free(peer); 172 173 memset(ops, 0, sizeof(ops)); 174 op = ops; 175 op->op = GRPC_OP_SEND_INITIAL_METADATA; 176 op->data.send_initial_metadata.count = 0; 177 op->flags = 0; 178 op->reserved = nullptr; 179 op++; 180 op->op = GRPC_OP_SEND_STATUS_FROM_SERVER; 181 op->data.send_status_from_server.trailing_metadata_count = 0; 182 op->data.send_status_from_server.status = GRPC_STATUS_UNIMPLEMENTED; 183 grpc_slice status_details = grpc_slice_from_static_string("xyz"); 184 op->data.send_status_from_server.status_details = &status_details; 185 op->flags = 0; 186 op->reserved = nullptr; 187 op++; 188 op->op = GRPC_OP_RECV_CLOSE_ON_SERVER; 189 op->data.recv_close_on_server.cancelled = &was_cancelled; 190 op->flags = 0; 191 op->reserved = nullptr; 192 op++; 193 error = grpc_call_start_batch(s, ops, static_cast<size_t>(op - ops), tag(102), 194 nullptr); 195 GPR_ASSERT(GRPC_CALL_OK == error); 196 197 CQ_EXPECT_COMPLETION(cqv, tag(102), 1); 198 CQ_EXPECT_COMPLETION(cqv, tag(1), 1); 199 cq_verify(cqv); 200 201 GPR_ASSERT(status == GRPC_STATUS_UNIMPLEMENTED); 202 GPR_ASSERT(0 == grpc_slice_str_cmp(details, "xyz")); 203 // the following sanity check makes sure that the requested error string is 204 // correctly populated by the core. It looks for certain substrings that are 205 // not likely to change much. Some parts of the error, like time created, 206 // obviously are not checked. 207 GPR_ASSERT(nullptr != strstr(error_string, "xyz")); 208 GPR_ASSERT(nullptr != strstr(error_string, "description")); 209 GPR_ASSERT(nullptr != strstr(error_string, "Error received from peer")); 210 GPR_ASSERT(nullptr != strstr(error_string, "grpc_message")); 211 GPR_ASSERT(nullptr != strstr(error_string, "grpc_status")); 212 GPR_ASSERT(0 == grpc_slice_str_cmp(call_details.method, "/foo")); 213 GPR_ASSERT(0 == call_details.flags); 214 GPR_ASSERT(was_cancelled == 1); 215 216 grpc_slice_unref(details); 217 gpr_free((void*)error_string); 218 grpc_metadata_array_destroy(&initial_metadata_recv); 219 grpc_metadata_array_destroy(&trailing_metadata_recv); 220 grpc_metadata_array_destroy(&request_metadata_recv); 221 grpc_call_details_destroy(&call_details); 222 223 grpc_call_unref(c); 224 grpc_call_unref(s); 225 226 cq_verifier_destroy(cqv); 227 228 grpc_stats_collect(after); 229 230 char* stats = grpc_stats_data_as_json(after); 231 gpr_log(GPR_DEBUG, "%s", stats); 232 gpr_free(stats); 233 234 int expected_calls = 1; 235 if (config.feature_mask & FEATURE_MASK_SUPPORTS_REQUEST_PROXYING) { 236 expected_calls *= 2; 237 } 238 #if defined(GRPC_COLLECT_STATS) || !defined(NDEBUG) 239 GPR_ASSERT(after->counters[GRPC_STATS_COUNTER_CLIENT_CALLS_CREATED] - 240 before->counters[GRPC_STATS_COUNTER_CLIENT_CALLS_CREATED] == 241 expected_calls); 242 GPR_ASSERT(after->counters[GRPC_STATS_COUNTER_SERVER_CALLS_CREATED] - 243 before->counters[GRPC_STATS_COUNTER_SERVER_CALLS_CREATED] == 244 expected_calls); 245 #endif /* defined(GRPC_COLLECT_STATS) || !defined(NDEBUG) */ 246 gpr_free(before); 247 gpr_free(after); 248 } 249 250 static void test_invoke_simple_request(grpc_end2end_test_config config) { 251 grpc_end2end_test_fixture f; 252 253 f = begin_test(config, "test_invoke_simple_request", nullptr, nullptr); 254 simple_request_body(config, f); 255 end_test(&f); 256 config.tear_down_data(&f); 257 } 258 259 static void test_invoke_10_simple_requests(grpc_end2end_test_config config) { 260 int i; 261 grpc_end2end_test_fixture f = 262 begin_test(config, "test_invoke_10_simple_requests", nullptr, nullptr); 263 for (i = 0; i < 10; i++) { 264 simple_request_body(config, f); 265 gpr_log(GPR_INFO, "Running test: Passed simple request %d", i); 266 } 267 end_test(&f); 268 config.tear_down_data(&f); 269 } 270 271 void simple_request(grpc_end2end_test_config config) { 272 int i; 273 for (i = 0; i < 10; i++) { 274 test_invoke_simple_request(config); 275 } 276 test_invoke_10_simple_requests(config); 277 } 278 279 void simple_request_pre_init(void) {} 280