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 "src/core/lib/transport/connectivity_state.h"
20
21 #include <string.h>
22
23 #include <grpc/support/log.h>
24
25 #include "src/core/lib/iomgr/exec_ctx.h"
26 #include "test/core/util/test_config.h"
27 #include "test/core/util/tracer_util.h"
28
29 #define THE_ARG ((void*)(size_t)0xcafebabe)
30
31 int g_counter;
32
must_succeed(void * arg,grpc_error * error)33 static void must_succeed(void* arg, grpc_error* error) {
34 GPR_ASSERT(error == GRPC_ERROR_NONE);
35 GPR_ASSERT(arg == THE_ARG);
36 g_counter++;
37 }
38
must_fail(void * arg,grpc_error * error)39 static void must_fail(void* arg, grpc_error* error) {
40 GPR_ASSERT(error != GRPC_ERROR_NONE);
41 GPR_ASSERT(arg == THE_ARG);
42 g_counter++;
43 }
44
test_connectivity_state_name(void)45 static void test_connectivity_state_name(void) {
46 gpr_log(GPR_DEBUG, "test_connectivity_state_name");
47 GPR_ASSERT(0 ==
48 strcmp(grpc_connectivity_state_name(GRPC_CHANNEL_IDLE), "IDLE"));
49 GPR_ASSERT(0 == strcmp(grpc_connectivity_state_name(GRPC_CHANNEL_CONNECTING),
50 "CONNECTING"));
51 GPR_ASSERT(0 ==
52 strcmp(grpc_connectivity_state_name(GRPC_CHANNEL_READY), "READY"));
53 GPR_ASSERT(
54 0 == strcmp(grpc_connectivity_state_name(GRPC_CHANNEL_TRANSIENT_FAILURE),
55 "TRANSIENT_FAILURE"));
56 GPR_ASSERT(0 == strcmp(grpc_connectivity_state_name(GRPC_CHANNEL_SHUTDOWN),
57 "SHUTDOWN"));
58 }
59
test_check(void)60 static void test_check(void) {
61 grpc_connectivity_state_tracker tracker;
62 grpc_core::ExecCtx exec_ctx;
63 grpc_error* error;
64 gpr_log(GPR_DEBUG, "test_check");
65 grpc_connectivity_state_init(&tracker, GRPC_CHANNEL_IDLE, "xxx");
66 GPR_ASSERT(grpc_connectivity_state_get(&tracker, &error) ==
67 GRPC_CHANNEL_IDLE);
68 GPR_ASSERT(grpc_connectivity_state_check(&tracker) == GRPC_CHANNEL_IDLE);
69 GPR_ASSERT(error == GRPC_ERROR_NONE);
70 grpc_connectivity_state_destroy(&tracker);
71 }
72
test_subscribe_then_unsubscribe(void)73 static void test_subscribe_then_unsubscribe(void) {
74 grpc_connectivity_state_tracker tracker;
75 grpc_closure* closure =
76 GRPC_CLOSURE_CREATE(must_fail, THE_ARG, grpc_schedule_on_exec_ctx);
77 grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
78 grpc_core::ExecCtx exec_ctx;
79 gpr_log(GPR_DEBUG, "test_subscribe_then_unsubscribe");
80 g_counter = 0;
81 grpc_connectivity_state_init(&tracker, GRPC_CHANNEL_IDLE, "xxx");
82 GPR_ASSERT(grpc_connectivity_state_notify_on_state_change(&tracker, &state,
83 closure));
84 grpc_core::ExecCtx::Get()->Flush();
85 GPR_ASSERT(state == GRPC_CHANNEL_IDLE);
86 GPR_ASSERT(g_counter == 0);
87 grpc_connectivity_state_notify_on_state_change(&tracker, nullptr, closure);
88 grpc_core::ExecCtx::Get()->Flush();
89 GPR_ASSERT(state == GRPC_CHANNEL_IDLE);
90 GPR_ASSERT(g_counter == 1);
91
92 grpc_connectivity_state_destroy(&tracker);
93 }
94
test_subscribe_then_destroy(void)95 static void test_subscribe_then_destroy(void) {
96 grpc_connectivity_state_tracker tracker;
97 grpc_closure* closure =
98 GRPC_CLOSURE_CREATE(must_succeed, THE_ARG, grpc_schedule_on_exec_ctx);
99 grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
100 grpc_core::ExecCtx exec_ctx;
101 gpr_log(GPR_DEBUG, "test_subscribe_then_destroy");
102 g_counter = 0;
103 grpc_connectivity_state_init(&tracker, GRPC_CHANNEL_IDLE, "xxx");
104 GPR_ASSERT(grpc_connectivity_state_notify_on_state_change(&tracker, &state,
105 closure));
106 grpc_core::ExecCtx::Get()->Flush();
107 GPR_ASSERT(state == GRPC_CHANNEL_IDLE);
108 GPR_ASSERT(g_counter == 0);
109 grpc_connectivity_state_destroy(&tracker);
110
111 grpc_core::ExecCtx::Get()->Flush();
112 GPR_ASSERT(state == GRPC_CHANNEL_SHUTDOWN);
113 GPR_ASSERT(g_counter == 1);
114 }
115
test_subscribe_with_failure_then_destroy(void)116 static void test_subscribe_with_failure_then_destroy(void) {
117 grpc_connectivity_state_tracker tracker;
118 grpc_closure* closure =
119 GRPC_CLOSURE_CREATE(must_fail, THE_ARG, grpc_schedule_on_exec_ctx);
120 grpc_connectivity_state state = GRPC_CHANNEL_SHUTDOWN;
121 grpc_core::ExecCtx exec_ctx;
122 gpr_log(GPR_DEBUG, "test_subscribe_with_failure_then_destroy");
123 g_counter = 0;
124 grpc_connectivity_state_init(&tracker, GRPC_CHANNEL_SHUTDOWN, "xxx");
125 GPR_ASSERT(0 == grpc_connectivity_state_notify_on_state_change(
126 &tracker, &state, closure));
127 grpc_core::ExecCtx::Get()->Flush();
128 GPR_ASSERT(state == GRPC_CHANNEL_SHUTDOWN);
129 GPR_ASSERT(g_counter == 0);
130 grpc_connectivity_state_destroy(&tracker);
131 grpc_core::ExecCtx::Get()->Flush();
132 GPR_ASSERT(state == GRPC_CHANNEL_SHUTDOWN);
133 GPR_ASSERT(g_counter == 1);
134 }
135
main(int argc,char ** argv)136 int main(int argc, char** argv) {
137 grpc_test_init(argc, argv);
138 grpc_init();
139 grpc_core::testing::grpc_tracer_enable_flag(&grpc_connectivity_state_trace);
140 test_connectivity_state_name();
141 test_check();
142 test_subscribe_then_unsubscribe();
143 test_subscribe_then_destroy();
144 test_subscribe_with_failure_then_destroy();
145 grpc_shutdown();
146 return 0;
147 }
148