connectivity_state_test.cc 8.4 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244
  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. #include "src/core/lib/transport/connectivity_state.h"
  19. #include <string.h>
  20. #include <gtest/gtest.h>
  21. #include <grpc/support/log.h>
  22. #include "src/core/lib/iomgr/exec_ctx.h"
  23. #include "test/core/util/test_config.h"
  24. #include "test/core/util/tracer_util.h"
  25. namespace grpc_core {
  26. namespace {
  27. TEST(ConnectivityStateName, Basic) {
  28. EXPECT_STREQ("IDLE", ConnectivityStateName(GRPC_CHANNEL_IDLE));
  29. EXPECT_STREQ("CONNECTING", ConnectivityStateName(GRPC_CHANNEL_CONNECTING));
  30. EXPECT_STREQ("READY", ConnectivityStateName(GRPC_CHANNEL_READY));
  31. EXPECT_STREQ("TRANSIENT_FAILURE",
  32. ConnectivityStateName(GRPC_CHANNEL_TRANSIENT_FAILURE));
  33. EXPECT_STREQ("SHUTDOWN", ConnectivityStateName(GRPC_CHANNEL_SHUTDOWN));
  34. }
  35. class Watcher : public ConnectivityStateWatcherInterface {
  36. public:
  37. Watcher(int* count, grpc_connectivity_state* output, absl::Status* status,
  38. bool* destroyed = nullptr)
  39. : count_(count),
  40. output_(output),
  41. status_(status),
  42. destroyed_(destroyed) {}
  43. ~Watcher() override {
  44. if (destroyed_ != nullptr) *destroyed_ = true;
  45. }
  46. void Notify(grpc_connectivity_state new_state,
  47. const absl::Status& status) override {
  48. ++*count_;
  49. *output_ = new_state;
  50. *status_ = status;
  51. }
  52. private:
  53. int* count_;
  54. grpc_connectivity_state* output_;
  55. absl::Status* status_;
  56. bool* destroyed_;
  57. };
  58. TEST(StateTracker, SetAndGetState) {
  59. ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_CONNECTING,
  60. absl::Status());
  61. EXPECT_EQ(tracker.state(), GRPC_CHANNEL_CONNECTING);
  62. EXPECT_TRUE(tracker.status().ok());
  63. tracker.SetState(GRPC_CHANNEL_READY, absl::Status(), "whee");
  64. EXPECT_EQ(tracker.state(), GRPC_CHANNEL_READY);
  65. EXPECT_TRUE(tracker.status().ok());
  66. absl::Status transient_failure_status(absl::StatusCode::kUnavailable,
  67. "status for testing");
  68. tracker.SetState(GRPC_CHANNEL_TRANSIENT_FAILURE, transient_failure_status,
  69. "reason");
  70. EXPECT_EQ(tracker.state(), GRPC_CHANNEL_TRANSIENT_FAILURE);
  71. EXPECT_EQ(tracker.status(), transient_failure_status);
  72. }
  73. TEST(StateTracker, NotificationUponAddingWatcher) {
  74. int count = 0;
  75. grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
  76. absl::Status status;
  77. ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_CONNECTING);
  78. tracker.AddWatcher(GRPC_CHANNEL_IDLE,
  79. MakeOrphanable<Watcher>(&count, &state, &status));
  80. EXPECT_EQ(count, 1);
  81. EXPECT_EQ(state, GRPC_CHANNEL_CONNECTING);
  82. EXPECT_TRUE(status.ok());
  83. }
  84. TEST(StateTracker, NotificationUponAddingWatcherWithTransientFailure) {
  85. int count = 0;
  86. grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
  87. absl::Status status;
  88. absl::Status transient_failure_status(absl::StatusCode::kUnavailable,
  89. "status for testing");
  90. ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_TRANSIENT_FAILURE,
  91. transient_failure_status);
  92. tracker.AddWatcher(GRPC_CHANNEL_IDLE,
  93. MakeOrphanable<Watcher>(&count, &state, &status));
  94. EXPECT_EQ(count, 1);
  95. EXPECT_EQ(state, GRPC_CHANNEL_TRANSIENT_FAILURE);
  96. EXPECT_EQ(status, transient_failure_status);
  97. }
  98. TEST(StateTracker, NotificationUponStateChange) {
  99. int count = 0;
  100. grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
  101. absl::Status status;
  102. ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_IDLE);
  103. tracker.AddWatcher(GRPC_CHANNEL_IDLE,
  104. MakeOrphanable<Watcher>(&count, &state, &status));
  105. EXPECT_EQ(count, 0);
  106. EXPECT_EQ(state, GRPC_CHANNEL_IDLE);
  107. EXPECT_TRUE(status.ok());
  108. absl::Status transient_failure_status(absl::StatusCode::kUnavailable,
  109. "status for testing");
  110. tracker.SetState(GRPC_CHANNEL_TRANSIENT_FAILURE, transient_failure_status,
  111. "whee");
  112. EXPECT_EQ(count, 1);
  113. EXPECT_EQ(state, GRPC_CHANNEL_TRANSIENT_FAILURE);
  114. EXPECT_EQ(status, transient_failure_status);
  115. }
  116. TEST(StateTracker, SubscribeThenUnsubscribe) {
  117. int count = 0;
  118. grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
  119. absl::Status status;
  120. bool destroyed = false;
  121. ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_IDLE);
  122. ConnectivityStateWatcherInterface* watcher =
  123. new Watcher(&count, &state, &status, &destroyed);
  124. tracker.AddWatcher(GRPC_CHANNEL_IDLE,
  125. OrphanablePtr<ConnectivityStateWatcherInterface>(watcher));
  126. // No initial notification, since we started the watch from the
  127. // current state.
  128. EXPECT_EQ(count, 0);
  129. EXPECT_EQ(state, GRPC_CHANNEL_IDLE);
  130. EXPECT_TRUE(status.ok());
  131. // Cancel watch. This should not generate another notification.
  132. tracker.RemoveWatcher(watcher);
  133. EXPECT_TRUE(destroyed);
  134. EXPECT_EQ(count, 0);
  135. EXPECT_EQ(state, GRPC_CHANNEL_IDLE);
  136. EXPECT_TRUE(status.ok());
  137. }
  138. TEST(StateTracker, OrphanUponShutdown) {
  139. int count = 0;
  140. grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
  141. absl::Status status;
  142. bool destroyed = false;
  143. ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_IDLE);
  144. ConnectivityStateWatcherInterface* watcher =
  145. new Watcher(&count, &state, &status, &destroyed);
  146. tracker.AddWatcher(GRPC_CHANNEL_IDLE,
  147. OrphanablePtr<ConnectivityStateWatcherInterface>(watcher));
  148. // No initial notification, since we started the watch from the
  149. // current state.
  150. EXPECT_EQ(count, 0);
  151. EXPECT_EQ(state, GRPC_CHANNEL_IDLE);
  152. EXPECT_TRUE(status.ok());
  153. // Set state to SHUTDOWN.
  154. tracker.SetState(GRPC_CHANNEL_SHUTDOWN, absl::Status(), "shutting down");
  155. EXPECT_TRUE(destroyed);
  156. EXPECT_EQ(count, 1);
  157. EXPECT_EQ(state, GRPC_CHANNEL_SHUTDOWN);
  158. EXPECT_TRUE(status.ok());
  159. }
  160. TEST(StateTracker, AddWhenAlreadyShutdown) {
  161. int count = 0;
  162. grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
  163. absl::Status status;
  164. bool destroyed = false;
  165. ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_SHUTDOWN,
  166. absl::Status());
  167. ConnectivityStateWatcherInterface* watcher =
  168. new Watcher(&count, &state, &status, &destroyed);
  169. tracker.AddWatcher(GRPC_CHANNEL_IDLE,
  170. OrphanablePtr<ConnectivityStateWatcherInterface>(watcher));
  171. EXPECT_TRUE(destroyed);
  172. EXPECT_EQ(count, 1);
  173. EXPECT_EQ(state, GRPC_CHANNEL_SHUTDOWN);
  174. EXPECT_TRUE(status.ok());
  175. }
  176. TEST(StateTracker, NotifyShutdownAtDestruction) {
  177. int count = 0;
  178. grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
  179. absl::Status status;
  180. {
  181. ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_IDLE);
  182. tracker.AddWatcher(GRPC_CHANNEL_IDLE,
  183. MakeOrphanable<Watcher>(&count, &state, &status));
  184. // No initial notification, since we started the watch from the
  185. // current state.
  186. EXPECT_EQ(count, 0);
  187. EXPECT_EQ(state, GRPC_CHANNEL_IDLE);
  188. }
  189. // Upon tracker destruction, we get a notification for SHUTDOWN.
  190. EXPECT_EQ(count, 1);
  191. EXPECT_EQ(state, GRPC_CHANNEL_SHUTDOWN);
  192. }
  193. TEST(StateTracker, DoNotNotifyShutdownAtDestructionIfAlreadyInShutdown) {
  194. int count = 0;
  195. grpc_connectivity_state state = GRPC_CHANNEL_SHUTDOWN;
  196. absl::Status status;
  197. {
  198. ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_SHUTDOWN);
  199. tracker.AddWatcher(GRPC_CHANNEL_SHUTDOWN,
  200. MakeOrphanable<Watcher>(&count, &state, &status));
  201. // No initial notification, since we started the watch from the
  202. // current state.
  203. EXPECT_EQ(count, 0);
  204. EXPECT_EQ(state, GRPC_CHANNEL_SHUTDOWN);
  205. }
  206. // No additional notification upon tracker destruction, since we were
  207. // already in state SHUTDOWN.
  208. EXPECT_EQ(count, 0);
  209. EXPECT_EQ(state, GRPC_CHANNEL_SHUTDOWN);
  210. }
  211. } // namespace
  212. } // namespace grpc_core
  213. int main(int argc, char** argv) {
  214. grpc::testing::TestEnvironment env(argc, argv);
  215. ::testing::InitGoogleTest(&argc, argv);
  216. grpc_init();
  217. grpc_core::testing::grpc_tracer_enable_flag(
  218. &grpc_core::grpc_connectivity_state_trace);
  219. int ret = RUN_ALL_TESTS();
  220. grpc_shutdown();
  221. return ret;
  222. }