network_change_notifier_unittest.cc 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317
  1. // Copyright (c) 2014 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 "net/base/network_change_notifier.h"
  5. #include "base/run_loop.h"
  6. #include "build/build_config.h"
  7. #include "net/base/mock_network_change_notifier.h"
  8. #include "net/base/network_interfaces.h"
  9. #include "net/test/test_with_task_environment.h"
  10. #include "testing/gtest/include/gtest/gtest.h"
  11. namespace net {
  12. // Note: This test is subject to the host's OS and network connection. This test
  13. // is not future-proof. New standards will come about necessitating the need to
  14. // alter the ranges of these tests.
  15. TEST(NetworkChangeNotifierTest, NetMaxBandwidthRange) {
  16. NetworkChangeNotifier::ConnectionType connection_type =
  17. NetworkChangeNotifier::CONNECTION_NONE;
  18. double max_bandwidth = 0.0;
  19. NetworkChangeNotifier::GetMaxBandwidthAndConnectionType(&max_bandwidth,
  20. &connection_type);
  21. // Always accept infinity as it's the default value if the bandwidth is
  22. // unknown.
  23. if (max_bandwidth == std::numeric_limits<double>::infinity()) {
  24. EXPECT_NE(NetworkChangeNotifier::CONNECTION_NONE, connection_type);
  25. return;
  26. }
  27. switch (connection_type) {
  28. case NetworkChangeNotifier::CONNECTION_UNKNOWN:
  29. EXPECT_EQ(std::numeric_limits<double>::infinity(), max_bandwidth);
  30. break;
  31. case NetworkChangeNotifier::CONNECTION_ETHERNET:
  32. EXPECT_GE(10.0, max_bandwidth);
  33. EXPECT_LE(10000.0, max_bandwidth);
  34. break;
  35. case NetworkChangeNotifier::CONNECTION_WIFI:
  36. EXPECT_GE(1.0, max_bandwidth);
  37. EXPECT_LE(7000.0, max_bandwidth);
  38. break;
  39. case NetworkChangeNotifier::CONNECTION_2G:
  40. EXPECT_GE(0.01, max_bandwidth);
  41. EXPECT_LE(0.384, max_bandwidth);
  42. break;
  43. case NetworkChangeNotifier::CONNECTION_3G:
  44. EXPECT_GE(2.0, max_bandwidth);
  45. EXPECT_LE(42.0, max_bandwidth);
  46. break;
  47. case NetworkChangeNotifier::CONNECTION_4G:
  48. EXPECT_GE(100.0, max_bandwidth);
  49. EXPECT_LE(100.0, max_bandwidth);
  50. break;
  51. case NetworkChangeNotifier::CONNECTION_5G:
  52. // TODO(crbug.com/1127134): Expect proper bounds once we have introduced
  53. // subtypes for 5G connections.
  54. EXPECT_EQ(std::numeric_limits<double>::infinity(), max_bandwidth);
  55. break;
  56. case NetworkChangeNotifier::CONNECTION_NONE:
  57. EXPECT_EQ(0.0, max_bandwidth);
  58. break;
  59. case NetworkChangeNotifier::CONNECTION_BLUETOOTH:
  60. EXPECT_GE(1.0, max_bandwidth);
  61. EXPECT_LE(24.0, max_bandwidth);
  62. break;
  63. }
  64. }
  65. TEST(NetworkChangeNotifierTest, ConnectionTypeFromInterfaceList) {
  66. NetworkInterfaceList list;
  67. // Test empty list.
  68. EXPECT_EQ(NetworkChangeNotifier::ConnectionTypeFromInterfaceList(list),
  69. NetworkChangeNotifier::CONNECTION_NONE);
  70. for (int i = NetworkChangeNotifier::CONNECTION_UNKNOWN;
  71. i <= NetworkChangeNotifier::CONNECTION_LAST; i++) {
  72. // Check individual types.
  73. NetworkInterface interface;
  74. interface.type = static_cast<NetworkChangeNotifier::ConnectionType>(i);
  75. list.clear();
  76. list.push_back(interface);
  77. EXPECT_EQ(NetworkChangeNotifier::ConnectionTypeFromInterfaceList(list), i);
  78. // Check two types.
  79. for (int j = NetworkChangeNotifier::CONNECTION_UNKNOWN;
  80. j <= NetworkChangeNotifier::CONNECTION_LAST; j++) {
  81. list.clear();
  82. interface.type = static_cast<NetworkChangeNotifier::ConnectionType>(i);
  83. list.push_back(interface);
  84. interface.type = static_cast<NetworkChangeNotifier::ConnectionType>(j);
  85. list.push_back(interface);
  86. EXPECT_EQ(NetworkChangeNotifier::ConnectionTypeFromInterfaceList(list),
  87. i == j ? i : NetworkChangeNotifier::CONNECTION_UNKNOWN);
  88. }
  89. }
  90. }
  91. TEST(NetworkChangeNotifierTest, IgnoreTeredoOnWindows) {
  92. NetworkInterfaceList list;
  93. NetworkInterface interface_teredo;
  94. interface_teredo.type = NetworkChangeNotifier::CONNECTION_ETHERNET;
  95. interface_teredo.friendly_name = "Teredo Tunneling Pseudo-Interface";
  96. list.push_back(interface_teredo);
  97. #if BUILDFLAG(IS_WIN)
  98. EXPECT_EQ(NetworkChangeNotifier::CONNECTION_NONE,
  99. NetworkChangeNotifier::ConnectionTypeFromInterfaceList(list));
  100. #else
  101. EXPECT_EQ(NetworkChangeNotifier::CONNECTION_ETHERNET,
  102. NetworkChangeNotifier::ConnectionTypeFromInterfaceList(list));
  103. #endif
  104. }
  105. TEST(NetworkChangeNotifierTest, IgnoreAirdropOnMac) {
  106. NetworkInterfaceList list;
  107. NetworkInterface interface_airdrop;
  108. interface_airdrop.type = NetworkChangeNotifier::CONNECTION_ETHERNET;
  109. interface_airdrop.name = "awdl0";
  110. interface_airdrop.friendly_name = "awdl0";
  111. interface_airdrop.address =
  112. // Link-local IPv6 address
  113. IPAddress({0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4});
  114. list.push_back(interface_airdrop);
  115. #if BUILDFLAG(IS_APPLE)
  116. EXPECT_EQ(NetworkChangeNotifier::CONNECTION_NONE,
  117. NetworkChangeNotifier::ConnectionTypeFromInterfaceList(list));
  118. #else
  119. EXPECT_EQ(NetworkChangeNotifier::CONNECTION_ETHERNET,
  120. NetworkChangeNotifier::ConnectionTypeFromInterfaceList(list));
  121. #endif
  122. }
  123. TEST(NetworkChangeNotifierTest, IgnoreTunnelsOnMac) {
  124. NetworkInterfaceList list;
  125. NetworkInterface interface_tunnel;
  126. interface_tunnel.type = NetworkChangeNotifier::CONNECTION_ETHERNET;
  127. interface_tunnel.name = "utun0";
  128. interface_tunnel.friendly_name = "utun0";
  129. interface_tunnel.address =
  130. // Link-local IPv6 address
  131. IPAddress({0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 3, 2, 1});
  132. list.push_back(interface_tunnel);
  133. #if BUILDFLAG(IS_APPLE)
  134. EXPECT_EQ(NetworkChangeNotifier::CONNECTION_NONE,
  135. NetworkChangeNotifier::ConnectionTypeFromInterfaceList(list));
  136. #else
  137. EXPECT_EQ(NetworkChangeNotifier::CONNECTION_ETHERNET,
  138. NetworkChangeNotifier::ConnectionTypeFromInterfaceList(list));
  139. #endif
  140. }
  141. TEST(NetworkChangeNotifierTest, IgnoreDisconnectedEthernetOnMac) {
  142. NetworkInterfaceList list;
  143. NetworkInterface interface_ethernet;
  144. interface_ethernet.type = NetworkChangeNotifier::CONNECTION_ETHERNET;
  145. interface_ethernet.name = "en5";
  146. interface_ethernet.friendly_name = "en5";
  147. interface_ethernet.address =
  148. // Link-local IPv6 address
  149. IPAddress({0xfe, 0x80, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 4, 1, 2, 3});
  150. list.push_back(interface_ethernet);
  151. #if BUILDFLAG(IS_APPLE)
  152. EXPECT_EQ(NetworkChangeNotifier::CONNECTION_NONE,
  153. NetworkChangeNotifier::ConnectionTypeFromInterfaceList(list));
  154. #else
  155. EXPECT_EQ(NetworkChangeNotifier::CONNECTION_ETHERNET,
  156. NetworkChangeNotifier::ConnectionTypeFromInterfaceList(list));
  157. #endif
  158. }
  159. TEST(NetworkChangeNotifierTest, IgnoreVMInterfaces) {
  160. NetworkInterfaceList list;
  161. NetworkInterface interface_vmnet_linux;
  162. interface_vmnet_linux.type = NetworkChangeNotifier::CONNECTION_ETHERNET;
  163. interface_vmnet_linux.name = "vmnet1";
  164. interface_vmnet_linux.friendly_name = "vmnet1";
  165. list.push_back(interface_vmnet_linux);
  166. NetworkInterface interface_vmnet_win;
  167. interface_vmnet_win.type = NetworkChangeNotifier::CONNECTION_ETHERNET;
  168. interface_vmnet_win.name = "virtualdevice";
  169. interface_vmnet_win.friendly_name = "VMware Network Adapter VMnet1";
  170. list.push_back(interface_vmnet_win);
  171. EXPECT_EQ(NetworkChangeNotifier::CONNECTION_NONE,
  172. NetworkChangeNotifier::ConnectionTypeFromInterfaceList(list));
  173. }
  174. TEST(NetworkChangeNotifierTest, GetConnectionSubtype) {
  175. // Call GetConnectionSubtype() and ensure that there is no crash.
  176. NetworkChangeNotifier::GetConnectionSubtype();
  177. }
  178. class NetworkChangeNotifierMockedTest : public TestWithTaskEnvironment {
  179. protected:
  180. test::ScopedMockNetworkChangeNotifier mock_notifier_;
  181. };
  182. class TestDnsObserver : public NetworkChangeNotifier::DNSObserver {
  183. public:
  184. void OnDNSChanged() override { ++dns_changed_calls_; }
  185. int dns_changed_calls() const { return dns_changed_calls_; }
  186. private:
  187. int dns_changed_calls_ = 0;
  188. };
  189. TEST_F(NetworkChangeNotifierMockedTest, TriggerNonSystemDnsChange) {
  190. TestDnsObserver observer;
  191. NetworkChangeNotifier::AddDNSObserver(&observer);
  192. ASSERT_EQ(0, observer.dns_changed_calls());
  193. NetworkChangeNotifier::TriggerNonSystemDnsChange();
  194. base::RunLoop().RunUntilIdle();
  195. EXPECT_EQ(1, observer.dns_changed_calls());
  196. NetworkChangeNotifier::RemoveDNSObserver(&observer);
  197. }
  198. class TestConnectionCostObserver
  199. : public NetworkChangeNotifier::ConnectionCostObserver {
  200. public:
  201. void OnConnectionCostChanged(
  202. NetworkChangeNotifier::ConnectionCost cost) override {
  203. cost_changed_inputs_.push_back(cost);
  204. ++cost_changed_calls_;
  205. }
  206. int cost_changed_calls() const { return cost_changed_calls_; }
  207. std::vector<NetworkChangeNotifier::ConnectionCost> cost_changed_inputs()
  208. const {
  209. return cost_changed_inputs_;
  210. }
  211. private:
  212. int cost_changed_calls_ = 0;
  213. std::vector<NetworkChangeNotifier::ConnectionCost> cost_changed_inputs_;
  214. };
  215. TEST_F(NetworkChangeNotifierMockedTest, TriggerConnectionCostChange) {
  216. TestConnectionCostObserver observer;
  217. NetworkChangeNotifier::AddConnectionCostObserver(&observer);
  218. ASSERT_EQ(0, observer.cost_changed_calls());
  219. NetworkChangeNotifier::NotifyObserversOfConnectionCostChangeForTests(
  220. NetworkChangeNotifier::CONNECTION_COST_METERED);
  221. base::RunLoop().RunUntilIdle();
  222. EXPECT_EQ(1, observer.cost_changed_calls());
  223. EXPECT_EQ(NetworkChangeNotifier::CONNECTION_COST_METERED,
  224. observer.cost_changed_inputs()[0]);
  225. NetworkChangeNotifier::RemoveConnectionCostObserver(&observer);
  226. NetworkChangeNotifier::NotifyObserversOfConnectionCostChangeForTests(
  227. NetworkChangeNotifier::CONNECTION_COST_UNMETERED);
  228. base::RunLoop().RunUntilIdle();
  229. EXPECT_EQ(1, observer.cost_changed_calls());
  230. }
  231. TEST_F(NetworkChangeNotifierMockedTest, ConnectionCostDefaultsToCellular) {
  232. mock_notifier_.mock_network_change_notifier()
  233. ->SetUseDefaultConnectionCostImplementation(true);
  234. mock_notifier_.mock_network_change_notifier()->SetConnectionType(
  235. NetworkChangeNotifier::CONNECTION_4G);
  236. EXPECT_TRUE(NetworkChangeNotifier::IsConnectionCellular(
  237. NetworkChangeNotifier::GetConnectionType()));
  238. EXPECT_EQ(NetworkChangeNotifier::CONNECTION_COST_METERED,
  239. NetworkChangeNotifier::GetConnectionCost());
  240. mock_notifier_.mock_network_change_notifier()->SetConnectionType(
  241. NetworkChangeNotifier::CONNECTION_WIFI);
  242. EXPECT_FALSE(NetworkChangeNotifier::IsConnectionCellular(
  243. NetworkChangeNotifier::GetConnectionType()));
  244. EXPECT_EQ(NetworkChangeNotifier::CONNECTION_COST_UNMETERED,
  245. NetworkChangeNotifier::GetConnectionCost());
  246. }
  247. class NetworkChangeNotifierConnectionCostTest : public TestWithTaskEnvironment {
  248. public:
  249. void SetUp() override {
  250. network_change_notifier_ = NetworkChangeNotifier::CreateIfNeeded();
  251. }
  252. private:
  253. // Allows creating a new NetworkChangeNotifier. Must be created before
  254. // |network_change_notifier_| and destroyed after it to avoid DCHECK failures.
  255. NetworkChangeNotifier::DisableForTest disable_for_test_;
  256. std::unique_ptr<NetworkChangeNotifier> network_change_notifier_;
  257. };
  258. TEST_F(NetworkChangeNotifierConnectionCostTest, GetConnectionCost) {
  259. EXPECT_NE(NetworkChangeNotifier::ConnectionCost::CONNECTION_COST_UNKNOWN,
  260. NetworkChangeNotifier::GetConnectionCost());
  261. }
  262. TEST_F(NetworkChangeNotifierConnectionCostTest, AddObserver) {
  263. TestConnectionCostObserver observer;
  264. EXPECT_NO_FATAL_FAILURE(
  265. NetworkChangeNotifier::AddConnectionCostObserver(&observer));
  266. // RunUntilIdle because the secondary work resulting from adding an observer
  267. // may be posted to a task queue.
  268. base::RunLoop().RunUntilIdle();
  269. }
  270. } // namespace net