Home | History | Annotate | Download | only in transport
      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