123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244 |
- /*
- *
- * Copyright 2015 gRPC authors.
- *
- * Licensed under the Apache License, Version 2.0 (the "License");
- * you may not use this file except in compliance with the License.
- * You may obtain a copy of the License at
- *
- * http://www.apache.org/licenses/LICENSE-2.0
- *
- * Unless required by applicable law or agreed to in writing, software
- * distributed under the License is distributed on an "AS IS" BASIS,
- * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
- * See the License for the specific language governing permissions and
- * limitations under the License.
- *
- */
- #include "src/core/lib/transport/connectivity_state.h"
- #include <string.h>
- #include <gtest/gtest.h>
- #include <grpc/support/log.h>
- #include "src/core/lib/iomgr/exec_ctx.h"
- #include "test/core/util/test_config.h"
- #include "test/core/util/tracer_util.h"
- namespace grpc_core {
- namespace {
- TEST(ConnectivityStateName, Basic) {
- EXPECT_STREQ("IDLE", ConnectivityStateName(GRPC_CHANNEL_IDLE));
- EXPECT_STREQ("CONNECTING", ConnectivityStateName(GRPC_CHANNEL_CONNECTING));
- EXPECT_STREQ("READY", ConnectivityStateName(GRPC_CHANNEL_READY));
- EXPECT_STREQ("TRANSIENT_FAILURE",
- ConnectivityStateName(GRPC_CHANNEL_TRANSIENT_FAILURE));
- EXPECT_STREQ("SHUTDOWN", ConnectivityStateName(GRPC_CHANNEL_SHUTDOWN));
- }
- class Watcher : public ConnectivityStateWatcherInterface {
- public:
- Watcher(int* count, grpc_connectivity_state* output, absl::Status* status,
- bool* destroyed = nullptr)
- : count_(count),
- output_(output),
- status_(status),
- destroyed_(destroyed) {}
- ~Watcher() override {
- if (destroyed_ != nullptr) *destroyed_ = true;
- }
- void Notify(grpc_connectivity_state new_state,
- const absl::Status& status) override {
- ++*count_;
- *output_ = new_state;
- *status_ = status;
- }
- private:
- int* count_;
- grpc_connectivity_state* output_;
- absl::Status* status_;
- bool* destroyed_;
- };
- TEST(StateTracker, SetAndGetState) {
- ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_CONNECTING,
- absl::Status());
- EXPECT_EQ(tracker.state(), GRPC_CHANNEL_CONNECTING);
- EXPECT_TRUE(tracker.status().ok());
- tracker.SetState(GRPC_CHANNEL_READY, absl::Status(), "whee");
- EXPECT_EQ(tracker.state(), GRPC_CHANNEL_READY);
- EXPECT_TRUE(tracker.status().ok());
- absl::Status transient_failure_status(absl::StatusCode::kUnavailable,
- "status for testing");
- tracker.SetState(GRPC_CHANNEL_TRANSIENT_FAILURE, transient_failure_status,
- "reason");
- EXPECT_EQ(tracker.state(), GRPC_CHANNEL_TRANSIENT_FAILURE);
- EXPECT_EQ(tracker.status(), transient_failure_status);
- }
- TEST(StateTracker, NotificationUponAddingWatcher) {
- int count = 0;
- grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
- absl::Status status;
- ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_CONNECTING);
- tracker.AddWatcher(GRPC_CHANNEL_IDLE,
- MakeOrphanable<Watcher>(&count, &state, &status));
- EXPECT_EQ(count, 1);
- EXPECT_EQ(state, GRPC_CHANNEL_CONNECTING);
- EXPECT_TRUE(status.ok());
- }
- TEST(StateTracker, NotificationUponAddingWatcherWithTransientFailure) {
- int count = 0;
- grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
- absl::Status status;
- absl::Status transient_failure_status(absl::StatusCode::kUnavailable,
- "status for testing");
- ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_TRANSIENT_FAILURE,
- transient_failure_status);
- tracker.AddWatcher(GRPC_CHANNEL_IDLE,
- MakeOrphanable<Watcher>(&count, &state, &status));
- EXPECT_EQ(count, 1);
- EXPECT_EQ(state, GRPC_CHANNEL_TRANSIENT_FAILURE);
- EXPECT_EQ(status, transient_failure_status);
- }
- TEST(StateTracker, NotificationUponStateChange) {
- int count = 0;
- grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
- absl::Status status;
- ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_IDLE);
- tracker.AddWatcher(GRPC_CHANNEL_IDLE,
- MakeOrphanable<Watcher>(&count, &state, &status));
- EXPECT_EQ(count, 0);
- EXPECT_EQ(state, GRPC_CHANNEL_IDLE);
- EXPECT_TRUE(status.ok());
- absl::Status transient_failure_status(absl::StatusCode::kUnavailable,
- "status for testing");
- tracker.SetState(GRPC_CHANNEL_TRANSIENT_FAILURE, transient_failure_status,
- "whee");
- EXPECT_EQ(count, 1);
- EXPECT_EQ(state, GRPC_CHANNEL_TRANSIENT_FAILURE);
- EXPECT_EQ(status, transient_failure_status);
- }
- TEST(StateTracker, SubscribeThenUnsubscribe) {
- int count = 0;
- grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
- absl::Status status;
- bool destroyed = false;
- ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_IDLE);
- ConnectivityStateWatcherInterface* watcher =
- new Watcher(&count, &state, &status, &destroyed);
- tracker.AddWatcher(GRPC_CHANNEL_IDLE,
- OrphanablePtr<ConnectivityStateWatcherInterface>(watcher));
- // No initial notification, since we started the watch from the
- // current state.
- EXPECT_EQ(count, 0);
- EXPECT_EQ(state, GRPC_CHANNEL_IDLE);
- EXPECT_TRUE(status.ok());
- // Cancel watch. This should not generate another notification.
- tracker.RemoveWatcher(watcher);
- EXPECT_TRUE(destroyed);
- EXPECT_EQ(count, 0);
- EXPECT_EQ(state, GRPC_CHANNEL_IDLE);
- EXPECT_TRUE(status.ok());
- }
- TEST(StateTracker, OrphanUponShutdown) {
- int count = 0;
- grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
- absl::Status status;
- bool destroyed = false;
- ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_IDLE);
- ConnectivityStateWatcherInterface* watcher =
- new Watcher(&count, &state, &status, &destroyed);
- tracker.AddWatcher(GRPC_CHANNEL_IDLE,
- OrphanablePtr<ConnectivityStateWatcherInterface>(watcher));
- // No initial notification, since we started the watch from the
- // current state.
- EXPECT_EQ(count, 0);
- EXPECT_EQ(state, GRPC_CHANNEL_IDLE);
- EXPECT_TRUE(status.ok());
- // Set state to SHUTDOWN.
- tracker.SetState(GRPC_CHANNEL_SHUTDOWN, absl::Status(), "shutting down");
- EXPECT_TRUE(destroyed);
- EXPECT_EQ(count, 1);
- EXPECT_EQ(state, GRPC_CHANNEL_SHUTDOWN);
- EXPECT_TRUE(status.ok());
- }
- TEST(StateTracker, AddWhenAlreadyShutdown) {
- int count = 0;
- grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
- absl::Status status;
- bool destroyed = false;
- ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_SHUTDOWN,
- absl::Status());
- ConnectivityStateWatcherInterface* watcher =
- new Watcher(&count, &state, &status, &destroyed);
- tracker.AddWatcher(GRPC_CHANNEL_IDLE,
- OrphanablePtr<ConnectivityStateWatcherInterface>(watcher));
- EXPECT_TRUE(destroyed);
- EXPECT_EQ(count, 1);
- EXPECT_EQ(state, GRPC_CHANNEL_SHUTDOWN);
- EXPECT_TRUE(status.ok());
- }
- TEST(StateTracker, NotifyShutdownAtDestruction) {
- int count = 0;
- grpc_connectivity_state state = GRPC_CHANNEL_IDLE;
- absl::Status status;
- {
- ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_IDLE);
- tracker.AddWatcher(GRPC_CHANNEL_IDLE,
- MakeOrphanable<Watcher>(&count, &state, &status));
- // No initial notification, since we started the watch from the
- // current state.
- EXPECT_EQ(count, 0);
- EXPECT_EQ(state, GRPC_CHANNEL_IDLE);
- }
- // Upon tracker destruction, we get a notification for SHUTDOWN.
- EXPECT_EQ(count, 1);
- EXPECT_EQ(state, GRPC_CHANNEL_SHUTDOWN);
- }
- TEST(StateTracker, DoNotNotifyShutdownAtDestructionIfAlreadyInShutdown) {
- int count = 0;
- grpc_connectivity_state state = GRPC_CHANNEL_SHUTDOWN;
- absl::Status status;
- {
- ConnectivityStateTracker tracker("xxx", GRPC_CHANNEL_SHUTDOWN);
- tracker.AddWatcher(GRPC_CHANNEL_SHUTDOWN,
- MakeOrphanable<Watcher>(&count, &state, &status));
- // No initial notification, since we started the watch from the
- // current state.
- EXPECT_EQ(count, 0);
- EXPECT_EQ(state, GRPC_CHANNEL_SHUTDOWN);
- }
- // No additional notification upon tracker destruction, since we were
- // already in state SHUTDOWN.
- EXPECT_EQ(count, 0);
- EXPECT_EQ(state, GRPC_CHANNEL_SHUTDOWN);
- }
- } // namespace
- } // namespace grpc_core
- int main(int argc, char** argv) {
- grpc::testing::TestEnvironment env(argc, argv);
- ::testing::InitGoogleTest(&argc, argv);
- grpc_init();
- grpc_core::testing::grpc_tracer_enable_flag(
- &grpc_core::grpc_connectivity_state_trace);
- int ret = RUN_ALL_TESTS();
- grpc_shutdown();
- return ret;
- }
|