blob: 8f46f0bb9132eb5d0ab457e3f4e0303d829b2c8e [file] [log] [blame]
Mark D. Roth5d11e432016-06-23 13:14:05 -07001/*
2 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02003 * Copyright 2016 gRPC authors.
Mark D. Roth5d11e432016-06-23 13:14:05 -07004 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02005 * 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
Mark D. Roth5d11e432016-06-23 13:14:05 -07008 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02009 * http://www.apache.org/licenses/LICENSE-2.0
Mark D. Roth5d11e432016-06-23 13:14:05 -070010 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +020011 * 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.
Mark D. Roth5d11e432016-06-23 13:14:05 -070016 *
17 */
18
19#include "test/core/end2end/end2end_tests.h"
20
Mark D. Roth44a2f252016-07-18 14:13:31 -070021#include <limits.h>
Mark D. Roth5d11e432016-06-23 13:14:05 -070022#include <stdbool.h>
23#include <stdio.h>
24#include <string.h>
25
26#include <grpc/byte_buffer.h>
27#include <grpc/support/alloc.h>
28#include <grpc/support/log.h>
29#include <grpc/support/time.h>
30#include <grpc/support/useful.h>
31#include "src/core/lib/channel/channel_stack_builder.h"
32#include "src/core/lib/surface/channel_init.h"
33#include "test/core/end2end/cq_verifier.h"
34
35enum { TIMEOUT = 200000 };
36
Mark D. Rothb7d833b2017-04-04 14:16:09 -070037static bool g_enable_server_channel_filter = false;
38static bool g_enable_client_channel_filter = false;
39static bool g_enable_client_subchannel_filter = false;
Mark D. Roth5d11e432016-06-23 13:14:05 -070040
Craig Tillerbaa14a92017-11-03 09:09:36 -070041static void* tag(intptr_t t) { return (void*)t; }
Mark D. Roth5d11e432016-06-23 13:14:05 -070042
43static grpc_end2end_test_fixture begin_test(grpc_end2end_test_config config,
Craig Tillerbaa14a92017-11-03 09:09:36 -070044 const char* test_name,
45 grpc_channel_args* client_args,
46 grpc_channel_args* server_args) {
Mark D. Roth5d11e432016-06-23 13:14:05 -070047 grpc_end2end_test_fixture f;
Robbie Shade55a046a2017-01-25 15:14:28 -050048 gpr_log(GPR_INFO, "Running test: %s/%s", test_name, config.name);
Mark D. Roth5d11e432016-06-23 13:14:05 -070049 f = config.create_fixture(client_args, server_args);
50 config.init_server(&f, server_args);
Mark D. Rothe127a392016-10-27 08:27:15 -070051 config.init_client(&f, client_args);
Mark D. Roth5d11e432016-06-23 13:14:05 -070052 return f;
53}
54
Chris Evansed2a5472017-03-27 17:34:51 -050055static gpr_timespec n_seconds_from_now(int n) {
Robbie Shadeca7effc2017-01-17 09:14:29 -050056 return grpc_timeout_seconds_to_deadline(n);
Mark D. Roth5d11e432016-06-23 13:14:05 -070057}
58
Chris Evansed2a5472017-03-27 17:34:51 -050059static gpr_timespec five_seconds_from_now(void) {
60 return n_seconds_from_now(5);
61}
Mark D. Roth5d11e432016-06-23 13:14:05 -070062
Craig Tillerbaa14a92017-11-03 09:09:36 -070063static void drain_cq(grpc_completion_queue* cq) {
Mark D. Roth5d11e432016-06-23 13:14:05 -070064 grpc_event ev;
65 do {
Craig Tiller4ac2b8e2017-11-10 14:14:17 -080066 ev = grpc_completion_queue_next(cq, five_seconds_from_now(), nullptr);
Mark D. Roth5d11e432016-06-23 13:14:05 -070067 } while (ev.type != GRPC_QUEUE_SHUTDOWN);
68}
69
Craig Tillerbaa14a92017-11-03 09:09:36 -070070static void shutdown_server(grpc_end2end_test_fixture* f) {
Mark D. Roth5d11e432016-06-23 13:14:05 -070071 if (!f->server) return;
Sree Kuchibhotla321881d2017-02-27 11:25:28 -080072 grpc_server_shutdown_and_notify(f->server, f->shutdown_cq, tag(1000));
73 GPR_ASSERT(grpc_completion_queue_pluck(f->shutdown_cq, tag(1000),
74 grpc_timeout_seconds_to_deadline(5),
Craig Tiller4ac2b8e2017-11-10 14:14:17 -080075 nullptr)
Mark D. Roth5d11e432016-06-23 13:14:05 -070076 .type == GRPC_OP_COMPLETE);
77 grpc_server_destroy(f->server);
Craig Tiller4ac2b8e2017-11-10 14:14:17 -080078 f->server = nullptr;
Mark D. Roth5d11e432016-06-23 13:14:05 -070079}
80
Craig Tillerbaa14a92017-11-03 09:09:36 -070081static void shutdown_client(grpc_end2end_test_fixture* f) {
Mark D. Roth5d11e432016-06-23 13:14:05 -070082 if (!f->client) return;
83 grpc_channel_destroy(f->client);
Craig Tiller4ac2b8e2017-11-10 14:14:17 -080084 f->client = nullptr;
Mark D. Roth5d11e432016-06-23 13:14:05 -070085}
86
Craig Tillerbaa14a92017-11-03 09:09:36 -070087static void end_test(grpc_end2end_test_fixture* f) {
Mark D. Roth5d11e432016-06-23 13:14:05 -070088 shutdown_server(f);
89 shutdown_client(f);
90
91 grpc_completion_queue_shutdown(f->cq);
92 drain_cq(f->cq);
93 grpc_completion_queue_destroy(f->cq);
Sree Kuchibhotla321881d2017-02-27 11:25:28 -080094 grpc_completion_queue_destroy(f->shutdown_cq);
Mark D. Roth5d11e432016-06-23 13:14:05 -070095}
96
Mark D. Rothb39bf852017-04-05 08:55:37 -070097// Simple request via a SERVER_CHANNEL filter that always fails to
Mark D. Rothe645d132017-04-05 06:47:35 -070098// initialize the call.
Mark D. Rothb7d833b2017-04-04 14:16:09 -070099static void test_server_channel_filter(grpc_end2end_test_config config) {
Craig Tillerbaa14a92017-11-03 09:09:36 -0700100 grpc_call* c;
101 grpc_call* s;
Craig Tiller28b72422016-10-26 21:15:29 -0700102 grpc_slice request_payload_slice =
103 grpc_slice_from_copied_string("hello world");
Craig Tillerbaa14a92017-11-03 09:09:36 -0700104 grpc_byte_buffer* request_payload =
Mark D. Roth5d11e432016-06-23 13:14:05 -0700105 grpc_raw_byte_buffer_create(&request_payload_slice, 1);
Mark D. Roth5d11e432016-06-23 13:14:05 -0700106 grpc_end2end_test_fixture f =
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800107 begin_test(config, "filter_call_init_fails", nullptr, nullptr);
Craig Tillerbaa14a92017-11-03 09:09:36 -0700108 cq_verifier* cqv = cq_verifier_create(f.cq);
Mark D. Roth5d11e432016-06-23 13:14:05 -0700109 grpc_op ops[6];
Craig Tillerbaa14a92017-11-03 09:09:36 -0700110 grpc_op* op;
Mark D. Roth5d11e432016-06-23 13:14:05 -0700111 grpc_metadata_array initial_metadata_recv;
112 grpc_metadata_array trailing_metadata_recv;
113 grpc_metadata_array request_metadata_recv;
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800114 grpc_byte_buffer* request_payload_recv = nullptr;
Mark D. Roth5d11e432016-06-23 13:14:05 -0700115 grpc_call_details call_details;
116 grpc_status_code status;
117 grpc_call_error error;
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800118 grpc_slice details;
Mark D. Roth5d11e432016-06-23 13:14:05 -0700119
Chris Evansed2a5472017-03-27 17:34:51 -0500120 gpr_timespec deadline = five_seconds_from_now();
Muxi Yan5ebd3272016-10-31 07:27:07 -0700121 c = grpc_channel_create_call(
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800122 f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800123 grpc_slice_from_static_string("/foo"),
124 get_host_override_slice("foo.test.google.fr:1234", config), deadline,
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800125 nullptr);
Mark D. Roth5d11e432016-06-23 13:14:05 -0700126 GPR_ASSERT(c);
127
128 grpc_metadata_array_init(&initial_metadata_recv);
129 grpc_metadata_array_init(&trailing_metadata_recv);
130 grpc_metadata_array_init(&request_metadata_recv);
131 grpc_call_details_init(&call_details);
132
133 memset(ops, 0, sizeof(ops));
134 op = ops;
135 op->op = GRPC_OP_SEND_INITIAL_METADATA;
136 op->data.send_initial_metadata.count = 0;
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800137 op->data.send_initial_metadata.metadata = nullptr;
Mark D. Roth5d11e432016-06-23 13:14:05 -0700138 op->flags = 0;
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800139 op->reserved = nullptr;
Mark D. Roth5d11e432016-06-23 13:14:05 -0700140 op++;
141 op->op = GRPC_OP_SEND_MESSAGE;
Mark D. Roth435f9f22017-01-25 12:53:54 -0800142 op->data.send_message.send_message = request_payload;
Mark D. Roth5d11e432016-06-23 13:14:05 -0700143 op->flags = 0;
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800144 op->reserved = nullptr;
Mark D. Roth5d11e432016-06-23 13:14:05 -0700145 op++;
146 op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
147 op->flags = 0;
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800148 op->reserved = nullptr;
Mark D. Roth5d11e432016-06-23 13:14:05 -0700149 op++;
150 op->op = GRPC_OP_RECV_INITIAL_METADATA;
Mark D. Roth435f9f22017-01-25 12:53:54 -0800151 op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
Mark D. Roth5d11e432016-06-23 13:14:05 -0700152 op->flags = 0;
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800153 op->reserved = nullptr;
Mark D. Roth5d11e432016-06-23 13:14:05 -0700154 op++;
155 op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
156 op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
157 op->data.recv_status_on_client.status = &status;
158 op->data.recv_status_on_client.status_details = &details;
Mark D. Roth5d11e432016-06-23 13:14:05 -0700159 op->flags = 0;
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800160 op->reserved = nullptr;
Mark D. Roth5d11e432016-06-23 13:14:05 -0700161 op++;
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800162 error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
Mark D. Roth5d11e432016-06-23 13:14:05 -0700163 GPR_ASSERT(GRPC_CALL_OK == error);
164
165 error =
166 grpc_server_request_call(f.server, &s, &call_details,
167 &request_metadata_recv, f.cq, f.cq, tag(101));
168 GPR_ASSERT(GRPC_CALL_OK == error);
169
Mark D. Roth7f9bba82016-08-25 08:35:42 -0700170 CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
Mark D. Roth5d11e432016-06-23 13:14:05 -0700171 cq_verify(cqv);
172
173 GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800174 GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
Mark D. Roth5d11e432016-06-23 13:14:05 -0700175
Craig Tiller7c70b6c2017-01-23 07:48:42 -0800176 grpc_slice_unref(details);
Mark D. Roth5d11e432016-06-23 13:14:05 -0700177 grpc_metadata_array_destroy(&initial_metadata_recv);
178 grpc_metadata_array_destroy(&trailing_metadata_recv);
179 grpc_metadata_array_destroy(&request_metadata_recv);
180 grpc_call_details_destroy(&call_details);
181
Craig Tillerdd36b152017-03-31 08:27:28 -0700182 grpc_call_unref(c);
Mark D. Roth5d11e432016-06-23 13:14:05 -0700183
184 cq_verifier_destroy(cqv);
185
186 grpc_byte_buffer_destroy(request_payload);
187 grpc_byte_buffer_destroy(request_payload_recv);
188
189 end_test(&f);
190 config.tear_down_data(&f);
191}
192
Mark D. Rothb39bf852017-04-05 08:55:37 -0700193// Simple request via a CLIENT_CHANNEL or CLIENT_DIRECT_CHANNEL filter
194// that always fails to initialize the call.
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700195static void test_client_channel_filter(grpc_end2end_test_config config) {
Craig Tillerbaa14a92017-11-03 09:09:36 -0700196 grpc_call* c;
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700197 grpc_slice request_payload_slice =
198 grpc_slice_from_copied_string("hello world");
Craig Tillerbaa14a92017-11-03 09:09:36 -0700199 grpc_byte_buffer* request_payload =
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700200 grpc_raw_byte_buffer_create(&request_payload_slice, 1);
Mark D. Rothe645d132017-04-05 06:47:35 -0700201 gpr_timespec deadline = five_seconds_from_now();
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700202 grpc_end2end_test_fixture f =
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800203 begin_test(config, "filter_call_init_fails", nullptr, nullptr);
Craig Tillerbaa14a92017-11-03 09:09:36 -0700204 cq_verifier* cqv = cq_verifier_create(f.cq);
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700205 grpc_op ops[6];
Craig Tillerbaa14a92017-11-03 09:09:36 -0700206 grpc_op* op;
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700207 grpc_metadata_array initial_metadata_recv;
208 grpc_metadata_array trailing_metadata_recv;
209 grpc_metadata_array request_metadata_recv;
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800210 grpc_byte_buffer* request_payload_recv = nullptr;
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700211 grpc_call_details call_details;
212 grpc_status_code status;
213 grpc_call_error error;
214 grpc_slice details;
215
216 c = grpc_channel_create_call(
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800217 f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700218 grpc_slice_from_static_string("/foo"),
219 get_host_override_slice("foo.test.google.fr:1234", config), deadline,
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800220 nullptr);
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700221 GPR_ASSERT(c);
222
223 grpc_metadata_array_init(&initial_metadata_recv);
224 grpc_metadata_array_init(&trailing_metadata_recv);
225 grpc_metadata_array_init(&request_metadata_recv);
226 grpc_call_details_init(&call_details);
227
228 memset(ops, 0, sizeof(ops));
229 op = ops;
230 op->op = GRPC_OP_SEND_INITIAL_METADATA;
231 op->data.send_initial_metadata.count = 0;
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800232 op->data.send_initial_metadata.metadata = nullptr;
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700233 op->flags = 0;
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800234 op->reserved = nullptr;
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700235 op++;
236 op->op = GRPC_OP_SEND_MESSAGE;
237 op->data.send_message.send_message = request_payload;
238 op->flags = 0;
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800239 op->reserved = nullptr;
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700240 op++;
241 op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
242 op->flags = 0;
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800243 op->reserved = nullptr;
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700244 op++;
245 op->op = GRPC_OP_RECV_INITIAL_METADATA;
246 op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
247 op->flags = 0;
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800248 op->reserved = nullptr;
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700249 op++;
250 op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
251 op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
252 op->data.recv_status_on_client.status = &status;
253 op->data.recv_status_on_client.status_details = &details;
254 op->flags = 0;
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800255 op->reserved = nullptr;
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700256 op++;
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800257 error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700258 GPR_ASSERT(GRPC_CALL_OK == error);
259
260 CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
261 cq_verify(cqv);
262
263 GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
264 GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
265
266 grpc_slice_unref(details);
267 grpc_metadata_array_destroy(&initial_metadata_recv);
268 grpc_metadata_array_destroy(&trailing_metadata_recv);
269 grpc_metadata_array_destroy(&request_metadata_recv);
270 grpc_call_details_destroy(&call_details);
271
Craig Tiller694cd702017-04-13 07:11:34 -0700272 grpc_call_unref(c);
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700273
274 cq_verifier_destroy(cqv);
275
276 grpc_byte_buffer_destroy(request_payload);
277 grpc_byte_buffer_destroy(request_payload_recv);
278
279 end_test(&f);
280 config.tear_down_data(&f);
281}
282
Mark D. Rothb39bf852017-04-05 08:55:37 -0700283// Simple request via a CLIENT_SUBCHANNEL filter that always fails to
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700284// initialize the call.
285static void test_client_subchannel_filter(grpc_end2end_test_config config) {
Craig Tillerbaa14a92017-11-03 09:09:36 -0700286 grpc_call* c;
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700287 grpc_slice request_payload_slice =
288 grpc_slice_from_copied_string("hello world");
Craig Tillerbaa14a92017-11-03 09:09:36 -0700289 grpc_byte_buffer* request_payload =
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700290 grpc_raw_byte_buffer_create(&request_payload_slice, 1);
Mark D. Rothe645d132017-04-05 06:47:35 -0700291 gpr_timespec deadline = five_seconds_from_now();
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700292 grpc_end2end_test_fixture f =
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800293 begin_test(config, "filter_call_init_fails", nullptr, nullptr);
Craig Tillerbaa14a92017-11-03 09:09:36 -0700294 cq_verifier* cqv = cq_verifier_create(f.cq);
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700295 grpc_op ops[6];
Craig Tillerbaa14a92017-11-03 09:09:36 -0700296 grpc_op* op;
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700297 grpc_metadata_array initial_metadata_recv;
298 grpc_metadata_array trailing_metadata_recv;
299 grpc_metadata_array request_metadata_recv;
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800300 grpc_byte_buffer* request_payload_recv = nullptr;
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700301 grpc_call_details call_details;
302 grpc_status_code status;
303 grpc_call_error error;
304 grpc_slice details;
305
306 c = grpc_channel_create_call(
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800307 f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700308 grpc_slice_from_static_string("/foo"),
309 get_host_override_slice("foo.test.google.fr:1234", config), deadline,
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800310 nullptr);
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700311 GPR_ASSERT(c);
312
313 grpc_metadata_array_init(&initial_metadata_recv);
314 grpc_metadata_array_init(&trailing_metadata_recv);
315 grpc_metadata_array_init(&request_metadata_recv);
316 grpc_call_details_init(&call_details);
317
318 memset(ops, 0, sizeof(ops));
319 op = ops;
320 op->op = GRPC_OP_SEND_INITIAL_METADATA;
321 op->data.send_initial_metadata.count = 0;
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800322 op->data.send_initial_metadata.metadata = nullptr;
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700323 op->flags = 0;
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800324 op->reserved = nullptr;
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700325 op++;
326 op->op = GRPC_OP_SEND_MESSAGE;
327 op->data.send_message.send_message = request_payload;
328 op->flags = 0;
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800329 op->reserved = nullptr;
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700330 op++;
331 op->op = GRPC_OP_SEND_CLOSE_FROM_CLIENT;
332 op->flags = 0;
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800333 op->reserved = nullptr;
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700334 op++;
335 op->op = GRPC_OP_RECV_INITIAL_METADATA;
336 op->data.recv_initial_metadata.recv_initial_metadata = &initial_metadata_recv;
337 op->flags = 0;
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800338 op->reserved = nullptr;
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700339 op++;
340 op->op = GRPC_OP_RECV_STATUS_ON_CLIENT;
341 op->data.recv_status_on_client.trailing_metadata = &trailing_metadata_recv;
342 op->data.recv_status_on_client.status = &status;
343 op->data.recv_status_on_client.status_details = &details;
344 op->flags = 0;
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800345 op->reserved = nullptr;
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700346 op++;
347
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800348 error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(1), nullptr);
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700349 GPR_ASSERT(GRPC_CALL_OK == error);
350
351 CQ_EXPECT_COMPLETION(cqv, tag(1), 1);
352 cq_verify(cqv);
353
354 GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
355 GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
356
357 // Reset and create a new call. (The first call uses a different code
358 // path in client_channel.c than subsequent calls on the same channel,
359 // and we need to test both.)
Craig Tiller694cd702017-04-13 07:11:34 -0700360 grpc_call_unref(c);
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700361 status = GRPC_STATUS_OK;
362 grpc_slice_unref(details);
363 details = grpc_empty_slice();
364
365 c = grpc_channel_create_call(
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800366 f.client, nullptr, GRPC_PROPAGATE_DEFAULTS, f.cq,
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700367 grpc_slice_from_static_string("/foo"),
368 get_host_override_slice("foo.test.google.fr:1234", config), deadline,
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800369 nullptr);
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700370 GPR_ASSERT(c);
371
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800372 error = grpc_call_start_batch(c, ops, (size_t)(op - ops), tag(2), nullptr);
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700373 GPR_ASSERT(GRPC_CALL_OK == error);
374
375 CQ_EXPECT_COMPLETION(cqv, tag(2), 1);
376 cq_verify(cqv);
377
378 GPR_ASSERT(status == GRPC_STATUS_PERMISSION_DENIED);
379 GPR_ASSERT(0 == grpc_slice_str_cmp(details, "access denied"));
380
381 grpc_slice_unref(details);
382 grpc_metadata_array_destroy(&initial_metadata_recv);
383 grpc_metadata_array_destroy(&trailing_metadata_recv);
384 grpc_metadata_array_destroy(&request_metadata_recv);
385 grpc_call_details_destroy(&call_details);
386
Craig Tiller694cd702017-04-13 07:11:34 -0700387 grpc_call_unref(c);
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700388
389 cq_verifier_destroy(cqv);
390
391 grpc_byte_buffer_destroy(request_payload);
392 grpc_byte_buffer_destroy(request_payload_recv);
393
394 end_test(&f);
395 config.tear_down_data(&f);
396}
397
Mark D. Roth5d11e432016-06-23 13:14:05 -0700398/*******************************************************************************
399 * Test filter - always fails to initialize a call
400 */
401
Yash Tibrewal8cf14702017-12-06 09:47:54 -0800402static grpc_error* init_call_elem(grpc_call_element* elem,
Craig Tillerbaa14a92017-11-03 09:09:36 -0700403 const grpc_call_element_args* args) {
ncteisen4b36a3d2017-03-13 19:08:06 -0700404 return grpc_error_set_int(
405 GRPC_ERROR_CREATE_FROM_STATIC_STRING("access denied"),
406 GRPC_ERROR_INT_GRPC_STATUS, GRPC_STATUS_PERMISSION_DENIED);
Mark D. Roth5d11e432016-06-23 13:14:05 -0700407}
408
Yash Tibrewal8cf14702017-12-06 09:47:54 -0800409static void destroy_call_elem(grpc_call_element* elem,
Craig Tillerbaa14a92017-11-03 09:09:36 -0700410 const grpc_call_final_info* final_info,
411 grpc_closure* ignored) {}
Mark D. Roth5d11e432016-06-23 13:14:05 -0700412
Yash Tibrewal8cf14702017-12-06 09:47:54 -0800413static grpc_error* init_channel_elem(grpc_channel_element* elem,
Craig Tillerbaa14a92017-11-03 09:09:36 -0700414 grpc_channel_element_args* args) {
Mark D. Roth5e2566e2016-11-18 10:53:13 -0800415 return GRPC_ERROR_NONE;
416}
Mark D. Roth5d11e432016-06-23 13:14:05 -0700417
Yash Tibrewal8cf14702017-12-06 09:47:54 -0800418static void destroy_channel_elem(grpc_channel_element* elem) {}
Mark D. Roth5d11e432016-06-23 13:14:05 -0700419
420static const grpc_channel_filter test_filter = {
421 grpc_call_next_op,
422 grpc_channel_next_op,
423 0,
424 init_call_elem,
425 grpc_call_stack_ignore_set_pollset_or_pollset_set,
426 destroy_call_elem,
427 0,
428 init_channel_elem,
429 destroy_channel_elem,
Mark D. Rothb2d24882016-10-27 15:44:07 -0700430 grpc_channel_next_get_info,
Mark D. Roth5d11e432016-06-23 13:14:05 -0700431 "filter_call_init_fails"};
432
433/*******************************************************************************
434 * Registration
435 */
436
Yash Tibrewal8cf14702017-12-06 09:47:54 -0800437static bool maybe_add_server_channel_filter(grpc_channel_stack_builder* builder,
Craig Tillerbaa14a92017-11-03 09:09:36 -0700438 void* arg) {
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700439 if (g_enable_server_channel_filter) {
Mark D. Rothb5f32f02016-07-19 08:36:52 -0700440 // Want to add the filter as close to the end as possible, to make
441 // sure that all of the filters work well together. However, we
442 // can't add it at the very end, because the connected channel filter
443 // must be the last one. So we add it right before the last one.
Craig Tillerbaa14a92017-11-03 09:09:36 -0700444 grpc_channel_stack_builder_iterator* it =
Mark D. Rothb5f32f02016-07-19 08:36:52 -0700445 grpc_channel_stack_builder_create_iterator_at_last(builder);
446 GPR_ASSERT(grpc_channel_stack_builder_move_prev(it));
Mark D. Roth05d73af2016-07-27 15:52:46 +0000447 const bool retval = grpc_channel_stack_builder_add_filter_before(
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800448 it, &test_filter, nullptr, nullptr);
Mark D. Roth05d73af2016-07-27 15:52:46 +0000449 grpc_channel_stack_builder_iterator_destroy(it);
450 return retval;
Mark D. Roth5d11e432016-06-23 13:14:05 -0700451 } else {
452 return true;
453 }
454}
455
Yash Tibrewal8cf14702017-12-06 09:47:54 -0800456static bool maybe_add_client_channel_filter(grpc_channel_stack_builder* builder,
Craig Tillerbaa14a92017-11-03 09:09:36 -0700457 void* arg) {
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700458 if (g_enable_client_channel_filter) {
459 // Want to add the filter as close to the end as possible, to make
460 // sure that all of the filters work well together. However, we
461 // can't add it at the very end, because the connected channel filter
462 // must be the last one. So we add it right before the last one.
Craig Tillerbaa14a92017-11-03 09:09:36 -0700463 grpc_channel_stack_builder_iterator* it =
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700464 grpc_channel_stack_builder_create_iterator_at_last(builder);
465 GPR_ASSERT(grpc_channel_stack_builder_move_prev(it));
466 const bool retval = grpc_channel_stack_builder_add_filter_before(
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800467 it, &test_filter, nullptr, nullptr);
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700468 grpc_channel_stack_builder_iterator_destroy(it);
469 return retval;
470 } else {
471 return true;
472 }
473}
474
475static bool maybe_add_client_subchannel_filter(
Yash Tibrewal8cf14702017-12-06 09:47:54 -0800476 grpc_channel_stack_builder* builder, void* arg) {
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700477 if (g_enable_client_subchannel_filter) {
478 // Want to add the filter as close to the end as possible, to make
479 // sure that all of the filters work well together. However, we
480 // can't add it at the very end, because the client channel filter
481 // must be the last one. So we add it right before the last one.
Craig Tillerbaa14a92017-11-03 09:09:36 -0700482 grpc_channel_stack_builder_iterator* it =
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700483 grpc_channel_stack_builder_create_iterator_at_last(builder);
484 GPR_ASSERT(grpc_channel_stack_builder_move_prev(it));
485 const bool retval = grpc_channel_stack_builder_add_filter_before(
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800486 it, &test_filter, nullptr, nullptr);
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700487 grpc_channel_stack_builder_iterator_destroy(it);
488 return retval;
489 } else {
490 return true;
491 }
492}
493
Mark D. Roth5d11e432016-06-23 13:14:05 -0700494static void init_plugin(void) {
Mark D. Roth44a2f252016-07-18 14:13:31 -0700495 grpc_channel_init_register_stage(GRPC_SERVER_CHANNEL, INT_MAX,
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800496 maybe_add_server_channel_filter, nullptr);
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700497 grpc_channel_init_register_stage(GRPC_CLIENT_CHANNEL, INT_MAX,
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800498 maybe_add_client_channel_filter, nullptr);
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700499 grpc_channel_init_register_stage(GRPC_CLIENT_SUBCHANNEL, INT_MAX,
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800500 maybe_add_client_subchannel_filter, nullptr);
Mark D. Rothb39bf852017-04-05 08:55:37 -0700501 grpc_channel_init_register_stage(GRPC_CLIENT_DIRECT_CHANNEL, INT_MAX,
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800502 maybe_add_client_channel_filter, nullptr);
Mark D. Roth5d11e432016-06-23 13:14:05 -0700503}
504
505static void destroy_plugin(void) {}
506
507void filter_call_init_fails(grpc_end2end_test_config config) {
Mark D. Rothb39bf852017-04-05 08:55:37 -0700508 gpr_log(GPR_INFO, "Testing SERVER_CHANNEL filter.");
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700509 g_enable_server_channel_filter = true;
510 test_server_channel_filter(config);
511 g_enable_server_channel_filter = false;
Mark D. Rothb39bf852017-04-05 08:55:37 -0700512 gpr_log(GPR_INFO, "Testing CLIENT_CHANNEL / CLIENT_DIRECT_CHANNEL filter.");
Mark D. Rothb7d833b2017-04-04 14:16:09 -0700513 g_enable_client_channel_filter = true;
514 test_client_channel_filter(config);
515 g_enable_client_channel_filter = false;
Mark D. Rothb39bf852017-04-05 08:55:37 -0700516 if (config.feature_mask & FEATURE_MASK_SUPPORTS_CLIENT_CHANNEL) {
517 gpr_log(GPR_INFO, "Testing CLIENT_SUBCHANNEL filter.");
518 g_enable_client_subchannel_filter = true;
519 test_client_subchannel_filter(config);
520 g_enable_client_subchannel_filter = false;
521 }
Mark D. Roth5d11e432016-06-23 13:14:05 -0700522}
523
524void filter_call_init_fails_pre_init(void) {
525 grpc_register_plugin(init_plugin, destroy_plugin);
526}