network_quality_estimator_manager_unittest.cc 12 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301
  1. // Copyright 2018 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_quality_estimator_manager.h"
  5. #include <algorithm>
  6. #include <memory>
  7. #include <utility>
  8. #include "base/memory/raw_ptr.h"
  9. #include "base/run_loop.h"
  10. #include "base/test/task_environment.h"
  11. #include "base/time/time.h"
  12. #include "mojo/public/cpp/bindings/receiver.h"
  13. #include "net/log/net_log.h"
  14. #include "net/nqe/effective_connection_type.h"
  15. #include "net/nqe/network_quality_estimator.h"
  16. #include "services/network/public/mojom/network_quality_estimator_manager.mojom.h"
  17. #include "testing/gtest/include/gtest/gtest.h"
  18. namespace network {
  19. namespace {
  20. class TestNetworkQualityEstimatorManagerClient
  21. : public mojom::NetworkQualityEstimatorManagerClient {
  22. public:
  23. explicit TestNetworkQualityEstimatorManagerClient(
  24. NetworkQualityEstimatorManager* network_quality_estimator_manager)
  25. : network_quality_estimator_manager_(network_quality_estimator_manager),
  26. num_network_quality_changed_(0),
  27. run_loop_(std::make_unique<base::RunLoop>()),
  28. effective_connection_type_(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN),
  29. http_rtt_(base::TimeDelta()),
  30. transport_rtt_(base::TimeDelta()),
  31. downlink_bandwidth_kbps_(INT32_MAX) {
  32. mojo::Remote<mojom::NetworkQualityEstimatorManager> manager;
  33. network_quality_estimator_manager_->AddReceiver(
  34. manager.BindNewPipeAndPassReceiver());
  35. manager->RequestNotifications(receiver_.BindNewPipeAndPassRemote());
  36. }
  37. TestNetworkQualityEstimatorManagerClient(
  38. const TestNetworkQualityEstimatorManagerClient&) = delete;
  39. TestNetworkQualityEstimatorManagerClient& operator=(
  40. const TestNetworkQualityEstimatorManagerClient&) = delete;
  41. ~TestNetworkQualityEstimatorManagerClient() override {}
  42. void OnNetworkQualityChanged(net::EffectiveConnectionType type,
  43. base::TimeDelta http_rtt,
  44. base::TimeDelta transport_rtt,
  45. int32_t downlink_bandwidth_kbps) override {
  46. num_network_quality_changed_++;
  47. effective_connection_type_ = type;
  48. http_rtt_ = http_rtt;
  49. transport_rtt_ = transport_rtt;
  50. downlink_bandwidth_kbps_ = downlink_bandwidth_kbps;
  51. if (run_loop_wait_effective_connection_type_ == type)
  52. run_loop_->Quit();
  53. }
  54. // Returns the number of OnNetworkQualityChanged() notifications. Note that
  55. // the number may change based on the order in which underlying network
  56. // quality estimator provides notifications when effective connection
  57. // type, RTT and downlink estimates change simultaneously.
  58. size_t num_network_quality_changed() const {
  59. return num_network_quality_changed_;
  60. }
  61. void WaitForNotification(
  62. net::EffectiveConnectionType effective_connection_type) {
  63. run_loop_wait_effective_connection_type_ = effective_connection_type;
  64. run_loop_->Run();
  65. run_loop_ = std::make_unique<base::RunLoop>();
  66. }
  67. net::EffectiveConnectionType effective_connection_type() const {
  68. return effective_connection_type_;
  69. }
  70. base::TimeDelta http_rtt() const { return http_rtt_; }
  71. base::TimeDelta transport_rtt() const { return transport_rtt_; }
  72. int32_t downlink_bandwidth_kbps() const { return downlink_bandwidth_kbps_; }
  73. private:
  74. raw_ptr<NetworkQualityEstimatorManager> network_quality_estimator_manager_;
  75. size_t num_network_quality_changed_;
  76. std::unique_ptr<base::RunLoop> run_loop_;
  77. net::EffectiveConnectionType run_loop_wait_effective_connection_type_;
  78. net::EffectiveConnectionType effective_connection_type_;
  79. base::TimeDelta http_rtt_;
  80. base::TimeDelta transport_rtt_;
  81. int32_t downlink_bandwidth_kbps_;
  82. mojo::Receiver<mojom::NetworkQualityEstimatorManagerClient> receiver_{this};
  83. };
  84. } // namespace
  85. class NetworkQualityEstimatorManagerTest : public testing::Test {
  86. public:
  87. NetworkQualityEstimatorManagerTest()
  88. : network_quality_estimator_manager_(
  89. std::make_unique<NetworkQualityEstimatorManager>(
  90. net::NetLog::Get())) {
  91. // Change the network quality to UNKNOWN to prevent any spurious
  92. // notifications.
  93. SimulateNetworkQualityChange(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN);
  94. network_quality_estimator_manager_client_ =
  95. std::make_unique<TestNetworkQualityEstimatorManagerClient>(
  96. network_quality_estimator_manager_.get());
  97. }
  98. NetworkQualityEstimatorManagerTest(
  99. const NetworkQualityEstimatorManagerTest&) = delete;
  100. NetworkQualityEstimatorManagerTest& operator=(
  101. const NetworkQualityEstimatorManagerTest&) = delete;
  102. ~NetworkQualityEstimatorManagerTest() override {}
  103. TestNetworkQualityEstimatorManagerClient*
  104. network_quality_estimator_manager_client() {
  105. return network_quality_estimator_manager_client_.get();
  106. }
  107. NetworkQualityEstimatorManager* network_quality_estimator_manager() const {
  108. return network_quality_estimator_manager_.get();
  109. }
  110. void SimulateNetworkQualityChange(net::EffectiveConnectionType type) {
  111. network_quality_estimator_manager_->GetNetworkQualityEstimator()
  112. ->SimulateNetworkQualityChangeForTesting(type);
  113. }
  114. private:
  115. base::test::TaskEnvironment task_environment_;
  116. std::unique_ptr<NetworkQualityEstimatorManager>
  117. network_quality_estimator_manager_;
  118. std::unique_ptr<TestNetworkQualityEstimatorManagerClient>
  119. network_quality_estimator_manager_client_;
  120. };
  121. TEST_F(NetworkQualityEstimatorManagerTest, ClientNotified) {
  122. // Simulate a new network quality change.
  123. SimulateNetworkQualityChange(net::EFFECTIVE_CONNECTION_TYPE_3G);
  124. network_quality_estimator_manager_client()->WaitForNotification(
  125. net::EFFECTIVE_CONNECTION_TYPE_3G);
  126. EXPECT_EQ(
  127. net::EFFECTIVE_CONNECTION_TYPE_3G,
  128. network_quality_estimator_manager_client()->effective_connection_type());
  129. base::RunLoop().RunUntilIdle();
  130. // Verify that not more than 2 notifications were received.
  131. EXPECT_GE(2u, network_quality_estimator_manager_client()
  132. ->num_network_quality_changed());
  133. // Typical RTT and downlink values when effective connection type is 3G. Taken
  134. // from net::NetworkQualityEstimatorParams.
  135. EXPECT_EQ(base::Milliseconds(450),
  136. network_quality_estimator_manager_client()->http_rtt());
  137. EXPECT_EQ(base::Milliseconds(400),
  138. network_quality_estimator_manager_client()->transport_rtt());
  139. EXPECT_EQ(
  140. 400,
  141. network_quality_estimator_manager_client()->downlink_bandwidth_kbps());
  142. }
  143. // Test that when the network quality is unavailable, network quality estimator
  144. // manager reports the estimated network quality values as negative.
  145. TEST_F(NetworkQualityEstimatorManagerTest,
  146. ClientNotifiedUnknownNetworkQuality) {
  147. EXPECT_EQ(
  148. net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN,
  149. network_quality_estimator_manager_client()->effective_connection_type());
  150. base::RunLoop().RunUntilIdle();
  151. SimulateNetworkQualityChange(net::EFFECTIVE_CONNECTION_TYPE_3G);
  152. network_quality_estimator_manager_client()->WaitForNotification(
  153. net::EFFECTIVE_CONNECTION_TYPE_3G);
  154. base::RunLoop().RunUntilIdle();
  155. // Typical RTT and downlink values when effective connection type is 3G. Taken
  156. // from net::NetworkQualityEstimatorParams.
  157. EXPECT_EQ(base::Milliseconds(450),
  158. network_quality_estimator_manager_client()->http_rtt());
  159. EXPECT_EQ(base::Milliseconds(400),
  160. network_quality_estimator_manager_client()->transport_rtt());
  161. EXPECT_EQ(
  162. 400,
  163. network_quality_estimator_manager_client()->downlink_bandwidth_kbps());
  164. SimulateNetworkQualityChange(net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN);
  165. network_quality_estimator_manager_client()->WaitForNotification(
  166. net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN);
  167. base::RunLoop().RunUntilIdle();
  168. EXPECT_GT(base::TimeDelta(),
  169. network_quality_estimator_manager_client()->http_rtt());
  170. EXPECT_GT(base::TimeDelta(),
  171. network_quality_estimator_manager_client()->transport_rtt());
  172. EXPECT_GT(
  173. 0, network_quality_estimator_manager_client()->downlink_bandwidth_kbps());
  174. }
  175. TEST_F(NetworkQualityEstimatorManagerTest, OneClientPipeBroken) {
  176. auto network_quality_estimator_manager_client2 =
  177. std::make_unique<TestNetworkQualityEstimatorManagerClient>(
  178. network_quality_estimator_manager());
  179. // Simulate a network quality change.
  180. SimulateNetworkQualityChange(net::EFFECTIVE_CONNECTION_TYPE_4G);
  181. network_quality_estimator_manager_client()->WaitForNotification(
  182. net::EFFECTIVE_CONNECTION_TYPE_4G);
  183. network_quality_estimator_manager_client2->WaitForNotification(
  184. net::EFFECTIVE_CONNECTION_TYPE_4G);
  185. EXPECT_EQ(
  186. net::EFFECTIVE_CONNECTION_TYPE_4G,
  187. network_quality_estimator_manager_client()->effective_connection_type());
  188. EXPECT_EQ(
  189. net::EFFECTIVE_CONNECTION_TYPE_4G,
  190. network_quality_estimator_manager_client2->effective_connection_type());
  191. // Typical RTT and downlink values when effective connection type is 4G. Taken
  192. // from net::NetworkQualityEstimatorParams.
  193. EXPECT_EQ(base::Milliseconds(175),
  194. network_quality_estimator_manager_client2->http_rtt());
  195. EXPECT_EQ(base::Milliseconds(125),
  196. network_quality_estimator_manager_client()->transport_rtt());
  197. EXPECT_EQ(
  198. 1600,
  199. network_quality_estimator_manager_client2->downlink_bandwidth_kbps());
  200. base::RunLoop().RunUntilIdle();
  201. EXPECT_GE(2u, network_quality_estimator_manager_client()
  202. ->num_network_quality_changed());
  203. EXPECT_GE(
  204. 2u,
  205. network_quality_estimator_manager_client2->num_network_quality_changed());
  206. network_quality_estimator_manager_client2.reset();
  207. base::RunLoop().RunUntilIdle();
  208. // Simulate a second network quality change, and the remaining client should
  209. // be notified.
  210. SimulateNetworkQualityChange(net::EFFECTIVE_CONNECTION_TYPE_2G);
  211. network_quality_estimator_manager_client()->WaitForNotification(
  212. net::EFFECTIVE_CONNECTION_TYPE_2G);
  213. EXPECT_EQ(
  214. net::EFFECTIVE_CONNECTION_TYPE_2G,
  215. network_quality_estimator_manager_client()->effective_connection_type());
  216. EXPECT_GE(3u, network_quality_estimator_manager_client()
  217. ->num_network_quality_changed());
  218. EXPECT_EQ(base::Milliseconds(1800),
  219. network_quality_estimator_manager_client()->http_rtt());
  220. EXPECT_EQ(base::Milliseconds(1500),
  221. network_quality_estimator_manager_client()->transport_rtt());
  222. EXPECT_EQ(
  223. 75,
  224. network_quality_estimator_manager_client()->downlink_bandwidth_kbps());
  225. }
  226. TEST_F(NetworkQualityEstimatorManagerTest,
  227. NewClientReceivesCurrentEffectiveType) {
  228. // Simulate a network quality change.
  229. SimulateNetworkQualityChange(net::EFFECTIVE_CONNECTION_TYPE_2G);
  230. network_quality_estimator_manager_client()->WaitForNotification(
  231. net::EFFECTIVE_CONNECTION_TYPE_2G);
  232. EXPECT_EQ(
  233. net::EFFECTIVE_CONNECTION_TYPE_2G,
  234. network_quality_estimator_manager_client()->effective_connection_type());
  235. base::RunLoop().RunUntilIdle();
  236. // Typical RTT and downlink values when effective connection type is 2G. Taken
  237. // from net::NetworkQualityEstimatorParams.
  238. EXPECT_EQ(base::Milliseconds(1800),
  239. network_quality_estimator_manager_client()->http_rtt());
  240. EXPECT_EQ(base::Milliseconds(1500),
  241. network_quality_estimator_manager_client()->transport_rtt());
  242. EXPECT_EQ(
  243. 75,
  244. network_quality_estimator_manager_client()->downlink_bandwidth_kbps());
  245. // Register a new client after the network quality change and it should
  246. // receive the up-to-date effective connection type.
  247. TestNetworkQualityEstimatorManagerClient
  248. network_quality_estimator_manager_client2(
  249. network_quality_estimator_manager());
  250. network_quality_estimator_manager_client2.WaitForNotification(
  251. net::EFFECTIVE_CONNECTION_TYPE_2G);
  252. EXPECT_EQ(
  253. net::EFFECTIVE_CONNECTION_TYPE_2G,
  254. network_quality_estimator_manager_client2.effective_connection_type());
  255. // Typical RTT and downlink values when when effective connection type is 2G.
  256. // Taken from net::NetworkQualityEstimatorParams.
  257. EXPECT_EQ(base::Milliseconds(1800),
  258. network_quality_estimator_manager_client2.http_rtt());
  259. EXPECT_EQ(base::Milliseconds(1500),
  260. network_quality_estimator_manager_client()->transport_rtt());
  261. EXPECT_EQ(
  262. 75, network_quality_estimator_manager_client2.downlink_bandwidth_kbps());
  263. }
  264. } // namespace network