blob: da65080bc06d584ba8fe97919e76105e69f46587 [file] [log] [blame]
Craig Tiller1ada6ad2015-07-16 16:19:14 -07001/*
2 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02003 * Copyright 2015 gRPC authors.
Craig Tiller1ada6ad2015-07-16 16:19:14 -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
Craig Tiller1ada6ad2015-07-16 16:19:14 -07008 *
Jan Tattermusch7897ae92017-06-07 22:57:36 +02009 * http://www.apache.org/licenses/LICENSE-2.0
Craig Tiller1ada6ad2015-07-16 16:19:14 -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.
Craig Tiller1ada6ad2015-07-16 16:19:14 -070016 *
17 */
18
19#include "test/core/end2end/end2end_tests.h"
20
21#include <grpc/support/log.h>
Craig Tiller8afeec82015-09-28 17:03:34 -070022#include <grpc/support/sync.h>
23#include <grpc/support/thd.h>
Craig Tiller1ada6ad2015-07-16 16:19:14 -070024#include <grpc/support/time.h>
25
26#include "test/core/end2end/cq_verifier.h"
27
Craig Tillerbaa14a92017-11-03 09:09:36 -070028static void* tag(intptr_t t) { return (void*)t; }
Craig Tiller1ada6ad2015-07-16 16:19:14 -070029
Craig Tiller8afeec82015-09-28 17:03:34 -070030typedef struct {
31 gpr_event started;
Craig Tillerbaa14a92017-11-03 09:09:36 -070032 grpc_channel* channel;
33 grpc_completion_queue* cq;
Craig Tiller8afeec82015-09-28 17:03:34 -070034} child_events;
35
Craig Tillerbaa14a92017-11-03 09:09:36 -070036static void child_thread(void* arg) {
37 child_events* ce = (child_events*)arg;
Craig Tiller8afeec82015-09-28 17:03:34 -070038 grpc_event ev;
Craig Tillerbaa14a92017-11-03 09:09:36 -070039 gpr_event_set(&ce->started, (void*)1);
Craig Tiller8afeec82015-09-28 17:03:34 -070040 gpr_log(GPR_DEBUG, "verifying");
Craig Tiller71a0f9d2015-09-28 17:22:01 -070041 ev = grpc_completion_queue_next(ce->cq, gpr_inf_future(GPR_CLOCK_MONOTONIC),
Craig Tiller4ac2b8e2017-11-10 14:14:17 -080042 nullptr);
Craig Tiller8afeec82015-09-28 17:03:34 -070043 GPR_ASSERT(ev.type == GRPC_OP_COMPLETE);
44 GPR_ASSERT(ev.tag == tag(1));
45 GPR_ASSERT(ev.success == 0);
46}
47
Craig Tiller1ada6ad2015-07-16 16:19:14 -070048static void test_connectivity(grpc_end2end_test_config config) {
Craig Tiller4ac2b8e2017-11-10 14:14:17 -080049 grpc_end2end_test_fixture f = config.create_fixture(nullptr, nullptr);
Craig Tiller1ada6ad2015-07-16 16:19:14 -070050 grpc_connectivity_state state;
Craig Tillerbaa14a92017-11-03 09:09:36 -070051 cq_verifier* cqv = cq_verifier_create(f.cq);
Craig Tiller8afeec82015-09-28 17:03:34 -070052 child_events ce;
53 gpr_thd_options thdopt = gpr_thd_options_default();
54 gpr_thd_id thdid;
Craig Tiller1ada6ad2015-07-16 16:19:14 -070055
David Garcia Quintas1edfb952016-11-22 17:15:34 -080056 grpc_channel_args client_args;
57 grpc_arg arg_array[1];
58 arg_array[0].type = GRPC_ARG_INTEGER;
Yash Tibrewal34a57d02017-10-23 15:33:21 -070059 arg_array[0].key =
Yash Tibrewal40422d52017-11-06 14:39:17 -080060 const_cast<char*>("grpc.testing.fixed_reconnect_backoff_ms");
David Garcia Quintas1edfb952016-11-22 17:15:34 -080061 arg_array[0].value.integer = 1000;
62 client_args.args = arg_array;
63 client_args.num_args = 1;
64
65 config.init_client(&f, &client_args);
Craig Tiller1ada6ad2015-07-16 16:19:14 -070066
Craig Tiller8afeec82015-09-28 17:03:34 -070067 ce.channel = f.client;
68 ce.cq = f.cq;
69 gpr_event_init(&ce.started);
70 gpr_thd_options_set_joinable(&thdopt);
Vijay Pai19988c62017-12-04 15:28:35 -080071 GPR_ASSERT(
72 gpr_thd_new(&thdid, "grpc_connectivity", child_thread, &ce, &thdopt));
Craig Tiller8afeec82015-09-28 17:03:34 -070073
74 gpr_event_wait(&ce.started, gpr_inf_future(GPR_CLOCK_MONOTONIC));
75
Craig Tiller1ada6ad2015-07-16 16:19:14 -070076 /* channels should start life in IDLE, and stay there */
Craig Tillerd6c98df2015-08-18 09:33:44 -070077 GPR_ASSERT(grpc_channel_check_connectivity_state(f.client, 0) ==
78 GRPC_CHANNEL_IDLE);
Robbie Shadeca7effc2017-01-17 09:14:29 -050079 gpr_sleep_until(grpc_timeout_milliseconds_to_deadline(100));
Craig Tillerd6c98df2015-08-18 09:33:44 -070080 GPR_ASSERT(grpc_channel_check_connectivity_state(f.client, 0) ==
81 GRPC_CHANNEL_IDLE);
Craig Tiller1ada6ad2015-07-16 16:19:14 -070082
83 /* start watching for a change */
Craig Tiller8afeec82015-09-28 17:03:34 -070084 gpr_log(GPR_DEBUG, "watching");
Craig Tiller71a0f9d2015-09-28 17:22:01 -070085 grpc_channel_watch_connectivity_state(
86 f.client, GRPC_CHANNEL_IDLE, gpr_now(GPR_CLOCK_MONOTONIC), f.cq, tag(1));
Craig Tiller8afeec82015-09-28 17:03:34 -070087
88 /* eventually the child thread completion should trigger */
89 gpr_thd_join(thdid);
Craig Tiller1ada6ad2015-07-16 16:19:14 -070090
91 /* check that we're still in idle, and start connecting */
Craig Tillerd6c98df2015-08-18 09:33:44 -070092 GPR_ASSERT(grpc_channel_check_connectivity_state(f.client, 1) ==
93 GRPC_CHANNEL_IDLE);
Craig Tiller8afeec82015-09-28 17:03:34 -070094 /* start watching for a change */
95 grpc_channel_watch_connectivity_state(f.client, GRPC_CHANNEL_IDLE,
Robbie Shadeca7effc2017-01-17 09:14:29 -050096 grpc_timeout_seconds_to_deadline(3),
Craig Tiller8afeec82015-09-28 17:03:34 -070097 f.cq, tag(2));
Craig Tiller1ada6ad2015-07-16 16:19:14 -070098
99 /* and now the watch should trigger */
Mark D. Roth7187ab92016-08-24 13:49:22 -0700100 CQ_EXPECT_COMPLETION(cqv, tag(2), 1);
Craig Tiller1ada6ad2015-07-16 16:19:14 -0700101 cq_verify(cqv);
Craig Tiller2cd9dd92015-07-31 16:34:37 -0700102 state = grpc_channel_check_connectivity_state(f.client, 0);
Craig Tillerd6c98df2015-08-18 09:33:44 -0700103 GPR_ASSERT(state == GRPC_CHANNEL_TRANSIENT_FAILURE ||
Craig Tiller74a096982015-07-31 17:16:22 -0700104 state == GRPC_CHANNEL_CONNECTING);
Craig Tiller1ada6ad2015-07-16 16:19:14 -0700105
106 /* quickly followed by a transition to TRANSIENT_FAILURE */
Craig Tillerd6c98df2015-08-18 09:33:44 -0700107 grpc_channel_watch_connectivity_state(f.client, GRPC_CHANNEL_CONNECTING,
Robbie Shadeca7effc2017-01-17 09:14:29 -0500108 grpc_timeout_seconds_to_deadline(3),
Craig Tiller8afeec82015-09-28 17:03:34 -0700109 f.cq, tag(3));
Mark D. Roth7187ab92016-08-24 13:49:22 -0700110 CQ_EXPECT_COMPLETION(cqv, tag(3), 1);
Craig Tiller1ada6ad2015-07-16 16:19:14 -0700111 cq_verify(cqv);
Craig Tiller2cd9dd92015-07-31 16:34:37 -0700112 state = grpc_channel_check_connectivity_state(f.client, 0);
Craig Tillerd6c98df2015-08-18 09:33:44 -0700113 GPR_ASSERT(state == GRPC_CHANNEL_TRANSIENT_FAILURE ||
Craig Tiller2cd9dd92015-07-31 16:34:37 -0700114 state == GRPC_CHANNEL_CONNECTING);
Craig Tiller1ada6ad2015-07-16 16:19:14 -0700115
116 gpr_log(GPR_DEBUG, "*** STARTING SERVER ***");
117
118 /* now let's bring up a server to connect to */
Craig Tiller4ac2b8e2017-11-10 14:14:17 -0800119 config.init_server(&f, nullptr);
Craig Tiller1ada6ad2015-07-16 16:19:14 -0700120
121 gpr_log(GPR_DEBUG, "*** STARTED SERVER ***");
122
123 /* we'll go through some set of transitions (some might be missed), until
124 READY is reached */
125 while (state != GRPC_CHANNEL_READY) {
Craig Tillerd6c98df2015-08-18 09:33:44 -0700126 grpc_channel_watch_connectivity_state(
Robbie Shadeca7effc2017-01-17 09:14:29 -0500127 f.client, state, grpc_timeout_seconds_to_deadline(3), f.cq, tag(4));
Mark D. Roth7187ab92016-08-24 13:49:22 -0700128 CQ_EXPECT_COMPLETION(cqv, tag(4), 1);
Craig Tiller1ada6ad2015-07-16 16:19:14 -0700129 cq_verify(cqv);
Craig Tiller2cd9dd92015-07-31 16:34:37 -0700130 state = grpc_channel_check_connectivity_state(f.client, 0);
Craig Tillerd6c98df2015-08-18 09:33:44 -0700131 GPR_ASSERT(state == GRPC_CHANNEL_READY ||
132 state == GRPC_CHANNEL_CONNECTING ||
Craig Tiller2cd9dd92015-07-31 16:34:37 -0700133 state == GRPC_CHANNEL_TRANSIENT_FAILURE);
Craig Tiller1ada6ad2015-07-16 16:19:14 -0700134 }
135
136 /* bring down the server again */
137 /* we should go immediately to TRANSIENT_FAILURE */
138 gpr_log(GPR_DEBUG, "*** SHUTTING DOWN SERVER ***");
139
Craig Tillerd6c98df2015-08-18 09:33:44 -0700140 grpc_channel_watch_connectivity_state(f.client, GRPC_CHANNEL_READY,
Robbie Shadeca7effc2017-01-17 09:14:29 -0500141 grpc_timeout_seconds_to_deadline(3),
Craig Tiller8afeec82015-09-28 17:03:34 -0700142 f.cq, tag(5));
Craig Tiller1ada6ad2015-07-16 16:19:14 -0700143
144 grpc_server_shutdown_and_notify(f.server, f.cq, tag(0xdead));
145
Mark D. Roth7187ab92016-08-24 13:49:22 -0700146 CQ_EXPECT_COMPLETION(cqv, tag(5), 1);
147 CQ_EXPECT_COMPLETION(cqv, tag(0xdead), 1);
Craig Tiller1ada6ad2015-07-16 16:19:14 -0700148 cq_verify(cqv);
Craig Tiller2cd9dd92015-07-31 16:34:37 -0700149 state = grpc_channel_check_connectivity_state(f.client, 0);
Craig Tillerd6c98df2015-08-18 09:33:44 -0700150 GPR_ASSERT(state == GRPC_CHANNEL_TRANSIENT_FAILURE ||
Craig Tillera6bebf42015-12-01 17:02:35 -0800151 state == GRPC_CHANNEL_CONNECTING || state == GRPC_CHANNEL_IDLE);
Craig Tiller1ada6ad2015-07-16 16:19:14 -0700152
153 /* cleanup server */
154 grpc_server_destroy(f.server);
155
156 gpr_log(GPR_DEBUG, "*** SHUTDOWN SERVER ***");
157
158 grpc_channel_destroy(f.client);
159 grpc_completion_queue_shutdown(f.cq);
160 grpc_completion_queue_destroy(f.cq);
Sree Kuchibhotla321881d2017-02-27 11:25:28 -0800161
162 /* shutdown_cq is not used in this test */
163 grpc_completion_queue_destroy(f.shutdown_cq);
Craig Tiller1ada6ad2015-07-16 16:19:14 -0700164 config.tear_down_data(&f);
165
166 cq_verifier_destroy(cqv);
167}
168
Craig Tiller521423c2016-02-22 22:22:22 -0800169void connectivity(grpc_end2end_test_config config) {
Craig Tiller1ada6ad2015-07-16 16:19:14 -0700170 GPR_ASSERT(config.feature_mask & FEATURE_MASK_SUPPORTS_DELAYED_CONNECTION);
171 test_connectivity(config);
172}
Craig Tiller9e9edbc2016-04-04 10:38:49 -0700173
174void connectivity_pre_init(void) {}