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 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 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 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 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 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 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 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 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