connection_scheduler_impl_unittest.cc 8.6 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209
  1. // Copyright 2020 The Chromium Authors. All rights reserved.
  2. // Use of this source code is governed by a BSD-style license that can be
  3. // found in the LICENSE file.
  4. #include "ash/components/phonehub/connection_scheduler_impl.h"
  5. #include <memory>
  6. #include "ash/components/phonehub/fake_feature_status_provider.h"
  7. #include "ash/components/phonehub/feature_status.h"
  8. #include "ash/services/secure_channel/public/cpp/client/fake_connection_manager.h"
  9. #include "base/test/task_environment.h"
  10. #include "base/time/time.h"
  11. #include "testing/gtest/include/gtest/gtest.h"
  12. namespace ash {
  13. namespace phonehub {
  14. class ConnectionSchedulerImplTest : public testing::Test {
  15. protected:
  16. ConnectionSchedulerImplTest() = default;
  17. ConnectionSchedulerImplTest(const ConnectionSchedulerImplTest&) = delete;
  18. ConnectionSchedulerImplTest& operator=(const ConnectionSchedulerImplTest&) =
  19. delete;
  20. ~ConnectionSchedulerImplTest() override = default;
  21. void SetUp() override {
  22. fake_connection_manager_ =
  23. std::make_unique<secure_channel::FakeConnectionManager>();
  24. fake_feature_status_provider_ =
  25. std::make_unique<FakeFeatureStatusProvider>();
  26. }
  27. void CreateConnectionScheduler() {
  28. connection_scheduler_ = std::make_unique<ConnectionSchedulerImpl>(
  29. fake_connection_manager_.get(), fake_feature_status_provider_.get());
  30. }
  31. base::TimeDelta GetCurrentBackoffDelay() {
  32. return connection_scheduler_->GetCurrentBackoffDelayTimeForTesting();
  33. }
  34. int GetBackoffFailureCount() {
  35. return connection_scheduler_->GetBackoffFailureCountForTesting();
  36. }
  37. base::test::TaskEnvironment task_environment_{
  38. base::test::TaskEnvironment::TimeSource::MOCK_TIME};
  39. std::unique_ptr<secure_channel::FakeConnectionManager>
  40. fake_connection_manager_;
  41. std::unique_ptr<FakeFeatureStatusProvider> fake_feature_status_provider_;
  42. std::unique_ptr<ConnectionSchedulerImpl> connection_scheduler_;
  43. };
  44. TEST_F(ConnectionSchedulerImplTest, SuccesssfullyAttemptConnection) {
  45. fake_feature_status_provider_->SetStatus(
  46. FeatureStatus::kEnabledButDisconnected);
  47. CreateConnectionScheduler();
  48. connection_scheduler_->ScheduleConnectionNow();
  49. // Verify that the ConnectionManager has attempted to connect.
  50. EXPECT_EQ(1u, fake_connection_manager_->num_attempt_connection_calls());
  51. // Simulate state changes with AttemptConnection().
  52. fake_feature_status_provider_->SetStatus(
  53. FeatureStatus::kEnabledAndConnecting);
  54. fake_feature_status_provider_->SetStatus(FeatureStatus::kEnabledAndConnected);
  55. // Verify only 1 call to AttemptConnection() was ever made.
  56. EXPECT_EQ(1u, fake_connection_manager_->num_attempt_connection_calls());
  57. // Verify that we did not attempt a backoff retry.
  58. EXPECT_EQ(0, GetBackoffFailureCount());
  59. }
  60. TEST_F(ConnectionSchedulerImplTest, FeatureDisabledDoesNotEstablishConnection) {
  61. fake_feature_status_provider_->SetStatus(FeatureStatus::kDisabled);
  62. CreateConnectionScheduler();
  63. connection_scheduler_->ScheduleConnectionNow();
  64. // Verify that the ConnectionManager did not attempt connection.
  65. EXPECT_EQ(0u, fake_connection_manager_->num_attempt_connection_calls());
  66. // Verify that we did not attempt a backoff retry.
  67. EXPECT_EQ(0, GetBackoffFailureCount());
  68. }
  69. TEST_F(ConnectionSchedulerImplTest, BackoffRetryWithUpdatedConnection) {
  70. fake_feature_status_provider_->SetStatus(
  71. FeatureStatus::kEnabledButDisconnected);
  72. CreateConnectionScheduler();
  73. connection_scheduler_->ScheduleConnectionNow();
  74. EXPECT_EQ(1u, fake_connection_manager_->num_attempt_connection_calls());
  75. // Simulate state changes with AttemptConnection().
  76. fake_feature_status_provider_->SetStatus(
  77. FeatureStatus::kEnabledAndConnecting);
  78. fake_feature_status_provider_->SetStatus(
  79. FeatureStatus::kEnabledButDisconnected);
  80. EXPECT_EQ(1, GetBackoffFailureCount());
  81. // Move forward time to the next backoff retry with disconnected status.
  82. task_environment_.FastForwardBy(GetCurrentBackoffDelay());
  83. EXPECT_EQ(2u, fake_connection_manager_->num_attempt_connection_calls());
  84. fake_feature_status_provider_->SetStatus(
  85. FeatureStatus::kEnabledAndConnecting);
  86. fake_feature_status_provider_->SetStatus(
  87. FeatureStatus::kEnabledButDisconnected);
  88. EXPECT_EQ(2, GetBackoffFailureCount());
  89. // Move forward time to the next backoff retry, this time with connected
  90. // status.
  91. task_environment_.FastForwardBy(GetCurrentBackoffDelay());
  92. EXPECT_EQ(3u, fake_connection_manager_->num_attempt_connection_calls());
  93. fake_feature_status_provider_->SetStatus(
  94. FeatureStatus::kEnabledAndConnecting);
  95. fake_feature_status_provider_->SetStatus(FeatureStatus::kEnabledAndConnected);
  96. // Expected no more backoff failures since connection is now established.
  97. EXPECT_EQ(0, GetBackoffFailureCount());
  98. // Fast forward time and confirm no other retries have been made.
  99. task_environment_.FastForwardBy(base::Seconds(100));
  100. EXPECT_EQ(3u, fake_connection_manager_->num_attempt_connection_calls());
  101. EXPECT_EQ(0, GetBackoffFailureCount());
  102. EXPECT_EQ(FeatureStatus::kEnabledAndConnected,
  103. fake_feature_status_provider_->GetStatus());
  104. }
  105. TEST_F(ConnectionSchedulerImplTest, BackoffRetryWithUpdatedFeatures) {
  106. fake_feature_status_provider_->SetStatus(
  107. FeatureStatus::kEnabledButDisconnected);
  108. CreateConnectionScheduler();
  109. connection_scheduler_->ScheduleConnectionNow();
  110. EXPECT_EQ(1u, fake_connection_manager_->num_attempt_connection_calls());
  111. // Simulate state changes with AttemptConnection().
  112. fake_feature_status_provider_->SetStatus(
  113. FeatureStatus::kEnabledAndConnecting);
  114. fake_feature_status_provider_->SetStatus(
  115. FeatureStatus::kEnabledButDisconnected);
  116. EXPECT_EQ(1, GetBackoffFailureCount());
  117. // Simulate the feature status switched to disabled.
  118. fake_feature_status_provider_->SetStatus(FeatureStatus::kDisabled);
  119. // Expect the backoff to reset and never attempt to kickoff another
  120. // connection.
  121. EXPECT_EQ(0, GetBackoffFailureCount());
  122. EXPECT_EQ(1u, fake_connection_manager_->num_attempt_connection_calls());
  123. // Expect that connection has been disconnected.
  124. EXPECT_EQ(1u, fake_connection_manager_->num_disconnect_calls());
  125. // Fast forward time and confirm no other retries have been made.
  126. task_environment_.FastForwardBy(base::Seconds(100));
  127. EXPECT_EQ(0, GetBackoffFailureCount());
  128. EXPECT_EQ(1u, fake_connection_manager_->num_attempt_connection_calls());
  129. // Simulate the feature re-enabled and the connection kickoff should start.
  130. fake_feature_status_provider_->SetStatus(
  131. FeatureStatus::kEnabledButDisconnected);
  132. // The next ScheduleConnection() was not caused by a previous failure, expect
  133. // backoff failure count to not increase.
  134. EXPECT_EQ(0, GetBackoffFailureCount());
  135. // Move forward in time and confirm backoff attempted another retry.
  136. task_environment_.FastForwardBy(GetCurrentBackoffDelay());
  137. EXPECT_EQ(2u, fake_connection_manager_->num_attempt_connection_calls());
  138. fake_feature_status_provider_->SetStatus(
  139. FeatureStatus::kEnabledAndConnecting);
  140. fake_feature_status_provider_->SetStatus(
  141. FeatureStatus::kEnabledButDisconnected);
  142. // The next ScheduleConnection() was caused by a previous failure, expect 1
  143. // failure count.
  144. EXPECT_EQ(1, GetBackoffFailureCount());
  145. }
  146. TEST_F(ConnectionSchedulerImplTest, ScheduleConnectionSuspended) {
  147. fake_feature_status_provider_->SetStatus(
  148. FeatureStatus::kEnabledButDisconnected);
  149. CreateConnectionScheduler();
  150. // Simulate screen locked and expect no scheduled connections.
  151. fake_feature_status_provider_->SetStatus(FeatureStatus::kLockOrSuspended);
  152. // Expect no scheduled connections on screen lock.
  153. EXPECT_EQ(0, GetBackoffFailureCount());
  154. EXPECT_EQ(0u, fake_connection_manager_->num_attempt_connection_calls());
  155. EXPECT_EQ(1u, fake_connection_manager_->num_disconnect_calls());
  156. // Simulate screen unlocked and expect a scheduled connection.
  157. fake_feature_status_provider_->SetStatus(
  158. FeatureStatus::kEnabledButDisconnected);
  159. EXPECT_EQ(0, GetBackoffFailureCount());
  160. EXPECT_EQ(1u, fake_connection_manager_->num_attempt_connection_calls());
  161. }
  162. TEST_F(ConnectionSchedulerImplTest, HostsNotEligible) {
  163. // Simulate no eligible hosts available. Expect no scheduled connections.
  164. fake_feature_status_provider_->SetStatus(
  165. FeatureStatus::kNotEligibleForFeature);
  166. CreateConnectionScheduler();
  167. EXPECT_EQ(0, GetBackoffFailureCount());
  168. EXPECT_EQ(0u, fake_connection_manager_->num_attempt_connection_calls());
  169. fake_feature_status_provider_->SetStatus(
  170. FeatureStatus::kEnabledButDisconnected);
  171. // Flip to have eligble hosts available. Expect a scheduled connection.
  172. EXPECT_EQ(0, GetBackoffFailureCount());
  173. EXPECT_EQ(1u, fake_connection_manager_->num_attempt_connection_calls());
  174. }
  175. } // namespace phonehub
  176. } // namespace ash