network_change_manager_unittest.cc 8.1 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223
  1. // Copyright 2017 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 "services/network/network_change_manager.h"
  5. #include <algorithm>
  6. #include <memory>
  7. #include <utility>
  8. #include "base/run_loop.h"
  9. #include "base/test/task_environment.h"
  10. #include "mojo/public/cpp/bindings/remote.h"
  11. #include "net/base/network_change_notifier.h"
  12. #include "services/network/public/mojom/network_change_manager.mojom.h"
  13. #include "testing/gtest/include/gtest/gtest.h"
  14. namespace network {
  15. namespace {
  16. // Type of notification expected in test.
  17. enum NotificationType {
  18. // Default value.
  19. NONE,
  20. // OnInitialConnectionType() notification.
  21. INITIAL,
  22. // OnNetworkChanged() notification.
  23. NETWORK_CHANGED,
  24. };
  25. class TestNetworkChangeManagerClient
  26. : public mojom::NetworkChangeManagerClient {
  27. public:
  28. explicit TestNetworkChangeManagerClient(
  29. NetworkChangeManager* network_change_manager)
  30. : num_network_changed_(0),
  31. run_loop_(std::make_unique<base::RunLoop>()),
  32. notification_type_to_wait_(NONE),
  33. connection_type_(mojom::ConnectionType::CONNECTION_UNKNOWN) {
  34. mojo::Remote<mojom::NetworkChangeManager> manager;
  35. network_change_manager->AddReceiver(manager.BindNewPipeAndPassReceiver());
  36. mojo::PendingRemote<mojom::NetworkChangeManagerClient> client_remote;
  37. receiver_.Bind(client_remote.InitWithNewPipeAndPassReceiver());
  38. manager->RequestNotifications(std::move(client_remote));
  39. }
  40. TestNetworkChangeManagerClient(const TestNetworkChangeManagerClient&) =
  41. delete;
  42. TestNetworkChangeManagerClient& operator=(
  43. const TestNetworkChangeManagerClient&) = delete;
  44. ~TestNetworkChangeManagerClient() override {}
  45. // NetworkChangeManagerClient implementation:
  46. void OnInitialConnectionType(mojom::ConnectionType type) override {
  47. connection_type_ = type;
  48. if (notification_type_to_wait_ == INITIAL)
  49. run_loop_->Quit();
  50. }
  51. void OnNetworkChanged(mojom::ConnectionType type) override {
  52. num_network_changed_++;
  53. connection_type_ = type;
  54. if (notification_type_to_wait_ == NETWORK_CHANGED)
  55. run_loop_->Quit();
  56. }
  57. // Returns the number of OnNetworkChanged() notifications.
  58. size_t num_network_changed() const { return num_network_changed_; }
  59. void WaitForNotification(NotificationType notification_type) {
  60. notification_type_to_wait_ = notification_type;
  61. run_loop_->Run();
  62. run_loop_ = std::make_unique<base::RunLoop>();
  63. }
  64. mojom::ConnectionType connection_type() const { return connection_type_; }
  65. private:
  66. size_t num_network_changed_;
  67. std::unique_ptr<base::RunLoop> run_loop_;
  68. NotificationType notification_type_to_wait_;
  69. mojom::ConnectionType connection_type_;
  70. mojo::Receiver<mojom::NetworkChangeManagerClient> receiver_{this};
  71. };
  72. } // namespace
  73. class NetworkChangeManagerTest : public testing::Test {
  74. public:
  75. NetworkChangeManagerTest()
  76. : network_change_manager_(new NetworkChangeManager(
  77. net::NetworkChangeNotifier::CreateMockIfNeeded())) {
  78. network_change_manager_client_ =
  79. std::make_unique<TestNetworkChangeManagerClient>(
  80. network_change_manager_.get());
  81. }
  82. NetworkChangeManagerTest(const NetworkChangeManagerTest&) = delete;
  83. NetworkChangeManagerTest& operator=(const NetworkChangeManagerTest&) = delete;
  84. ~NetworkChangeManagerTest() override {}
  85. TestNetworkChangeManagerClient* network_change_manager_client() {
  86. return network_change_manager_client_.get();
  87. }
  88. NetworkChangeManager* network_change_manager() const {
  89. return network_change_manager_.get();
  90. }
  91. void SimulateNetworkChange(net::NetworkChangeNotifier::ConnectionType type) {
  92. net::NetworkChangeNotifier::NotifyObserversOfNetworkChangeForTests(type);
  93. }
  94. private:
  95. base::test::TaskEnvironment task_environment_;
  96. std::unique_ptr<NetworkChangeManager> network_change_manager_;
  97. std::unique_ptr<TestNetworkChangeManagerClient>
  98. network_change_manager_client_;
  99. };
  100. TEST_F(NetworkChangeManagerTest, ClientNotified) {
  101. // Simulate a new network change.
  102. SimulateNetworkChange(net::NetworkChangeNotifier::CONNECTION_3G);
  103. network_change_manager_client()->WaitForNotification(NETWORK_CHANGED);
  104. EXPECT_EQ(mojom::ConnectionType::CONNECTION_3G,
  105. network_change_manager_client()->connection_type());
  106. base::RunLoop().RunUntilIdle();
  107. EXPECT_EQ(1u, network_change_manager_client()->num_network_changed());
  108. }
  109. TEST_F(NetworkChangeManagerTest, OneClientPipeBroken) {
  110. auto network_change_manager_client2 =
  111. std::make_unique<TestNetworkChangeManagerClient>(
  112. network_change_manager());
  113. // Simulate a network change.
  114. SimulateNetworkChange(net::NetworkChangeNotifier::CONNECTION_WIFI);
  115. network_change_manager_client()->WaitForNotification(NETWORK_CHANGED);
  116. network_change_manager_client2->WaitForNotification(NETWORK_CHANGED);
  117. EXPECT_EQ(mojom::ConnectionType::CONNECTION_WIFI,
  118. network_change_manager_client2->connection_type());
  119. base::RunLoop().RunUntilIdle();
  120. EXPECT_EQ(2u, network_change_manager()->GetNumClientsForTesting());
  121. EXPECT_EQ(1u, network_change_manager_client()->num_network_changed());
  122. EXPECT_EQ(1u, network_change_manager_client2->num_network_changed());
  123. network_change_manager_client2.reset();
  124. base::RunLoop().RunUntilIdle();
  125. EXPECT_EQ(1u, network_change_manager()->GetNumClientsForTesting());
  126. // Simulate a second network change, and the remaining client should be
  127. // notified.
  128. SimulateNetworkChange(net::NetworkChangeNotifier::CONNECTION_2G);
  129. network_change_manager_client()->WaitForNotification(NETWORK_CHANGED);
  130. EXPECT_EQ(mojom::ConnectionType::CONNECTION_2G,
  131. network_change_manager_client()->connection_type());
  132. EXPECT_EQ(2u, network_change_manager_client()->num_network_changed());
  133. }
  134. TEST_F(NetworkChangeManagerTest, NewClientReceivesCurrentType) {
  135. // Simulate a network change.
  136. SimulateNetworkChange(net::NetworkChangeNotifier::CONNECTION_BLUETOOTH);
  137. network_change_manager_client()->WaitForNotification(NETWORK_CHANGED);
  138. EXPECT_EQ(mojom::ConnectionType::CONNECTION_BLUETOOTH,
  139. network_change_manager_client()->connection_type());
  140. base::RunLoop().RunUntilIdle();
  141. // Register a new client after the network change and it should receive the
  142. // up-to-date connection type.
  143. TestNetworkChangeManagerClient network_change_manager_client2(
  144. network_change_manager());
  145. network_change_manager_client2.WaitForNotification(INITIAL);
  146. EXPECT_EQ(mojom::ConnectionType::CONNECTION_BLUETOOTH,
  147. network_change_manager_client2.connection_type());
  148. }
  149. TEST(NetworkChangeConnectionTypeTest, ConnectionTypeEnumMatch) {
  150. for (int typeInt = net::NetworkChangeNotifier::CONNECTION_UNKNOWN;
  151. typeInt != net::NetworkChangeNotifier::CONNECTION_LAST; typeInt++) {
  152. mojom::ConnectionType mojoType = mojom::ConnectionType(typeInt);
  153. switch (typeInt) {
  154. case net::NetworkChangeNotifier::CONNECTION_UNKNOWN:
  155. EXPECT_EQ(mojom::ConnectionType::CONNECTION_UNKNOWN, mojoType);
  156. break;
  157. case net::NetworkChangeNotifier::CONNECTION_ETHERNET:
  158. EXPECT_EQ(mojom::ConnectionType::CONNECTION_ETHERNET, mojoType);
  159. break;
  160. case net::NetworkChangeNotifier::CONNECTION_WIFI:
  161. EXPECT_EQ(mojom::ConnectionType::CONNECTION_WIFI, mojoType);
  162. break;
  163. case net::NetworkChangeNotifier::CONNECTION_2G:
  164. EXPECT_EQ(mojom::ConnectionType::CONNECTION_2G, mojoType);
  165. break;
  166. case net::NetworkChangeNotifier::CONNECTION_3G:
  167. EXPECT_EQ(mojom::ConnectionType::CONNECTION_3G, mojoType);
  168. break;
  169. case net::NetworkChangeNotifier::CONNECTION_4G:
  170. EXPECT_EQ(mojom::ConnectionType::CONNECTION_4G, mojoType);
  171. break;
  172. case net::NetworkChangeNotifier::CONNECTION_NONE:
  173. EXPECT_EQ(mojom::ConnectionType::CONNECTION_NONE, mojoType);
  174. break;
  175. case net::NetworkChangeNotifier::CONNECTION_BLUETOOTH:
  176. EXPECT_EQ(mojom::ConnectionType::CONNECTION_BLUETOOTH, mojoType);
  177. break;
  178. case net::NetworkChangeNotifier::CONNECTION_5G:
  179. EXPECT_EQ(mojom::ConnectionType::CONNECTION_5G, mojoType);
  180. EXPECT_EQ(mojom::ConnectionType::CONNECTION_LAST, mojoType);
  181. break;
  182. }
  183. }
  184. }
  185. } // namespace network