| OLD | NEW |
| 1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
| 2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
| 3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
| 4 | 4 |
| 5 #include "net/base/network_quality_estimator.h" | 5 #include "net/base/network_quality_estimator.h" |
| 6 | 6 |
| 7 #include <limits> | 7 #include <limits> |
| 8 | 8 |
| 9 #include "base/basictypes.h" | 9 #include "base/basictypes.h" |
| 10 #include "base/logging.h" | 10 #include "base/logging.h" |
| 11 #include "base/memory/scoped_ptr.h" | 11 #include "base/memory/scoped_ptr.h" |
| 12 #include "base/run_loop.h" | 12 #include "base/run_loop.h" |
| 13 #include "base/strings/safe_sprintf.h" |
| 13 #include "base/test/histogram_tester.h" | 14 #include "base/test/histogram_tester.h" |
| 14 #include "base/time/time.h" | 15 #include "base/time/time.h" |
| 15 #include "build/build_config.h" | 16 #include "build/build_config.h" |
| 16 #include "net/base/network_change_notifier.h" | 17 #include "net/base/network_change_notifier.h" |
| 17 #include "net/base/network_quality.h" | 18 #include "net/base/network_quality.h" |
| 18 #include "net/test/embedded_test_server/embedded_test_server.h" | 19 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 19 #include "net/url_request/url_request_test_util.h" | 20 #include "net/url_request/url_request_test_util.h" |
| 20 #include "testing/gtest/include/gtest/gtest.h" | 21 #include "testing/gtest/include/gtest/gtest.h" |
| 21 #include "url/gurl.h" | 22 #include "url/gurl.h" |
| 22 | 23 |
| 24 namespace { |
| 25 |
| 26 // Helps in setting the current network type and id. |
| 27 class TestNetworkQualityEstimator : public net::NetworkQualityEstimator { |
| 28 public: |
| 29 TestNetworkQualityEstimator() {} |
| 30 |
| 31 ~TestNetworkQualityEstimator() override {} |
| 32 |
| 33 // Overrides the current network type and id. |
| 34 // Notifies network quality estimator of change in connection. |
| 35 void SimulateNetworkChangeTo(net::NetworkChangeNotifier::ConnectionType type, |
| 36 std::string network_id) { |
| 37 current_network_id_ = network_id; |
| 38 OnConnectionTypeChanged(type); |
| 39 } |
| 40 |
| 41 using NetworkQualityEstimator::GetNetworkQualityCacheSizeForTests; |
| 42 using NetworkQualityEstimator::ReadCachedNetworkQualityEstimate; |
| 43 using NetworkQualityEstimator::OnConnectionTypeChanged; |
| 44 |
| 45 private: |
| 46 // NetworkQualityEstimator implementation that returns the overridden network |
| 47 // id (instead of invoking platform APIs). |
| 48 std::string GetCurrentNetworkName() const override { |
| 49 return current_network_id_; |
| 50 } |
| 51 |
| 52 std::string current_network_id_; |
| 53 }; |
| 54 |
| 55 } // namespace |
| 56 |
| 23 namespace net { | 57 namespace net { |
| 24 | 58 |
| 25 TEST(NetworkQualityEstimatorTest, TestPeakKbpsFastestRTTUpdates) { | 59 TEST(NetworkQualityEstimatorTest, TestPeakKbpsFastestRTTUpdates) { |
| 26 net::test_server::EmbeddedTestServer embedded_test_server; | 60 net::test_server::EmbeddedTestServer embedded_test_server; |
| 27 embedded_test_server.ServeFilesFromDirectory( | 61 embedded_test_server.ServeFilesFromDirectory( |
| 28 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); | 62 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); |
| 29 ASSERT_TRUE(embedded_test_server.InitializeAndWaitUntilReady()); | 63 ASSERT_TRUE(embedded_test_server.InitializeAndWaitUntilReady()); |
| 30 | 64 |
| 31 // Enable requests to local host to be used for network quality estimation. | 65 // Enable requests to local host to be used for network quality estimation. |
| 32 NetworkQualityEstimator estimator(true, true); | 66 NetworkQualityEstimator estimator(true, true); |
| (...skipping 26 matching lines...) Expand all Loading... |
| 59 base::HistogramTester histogram_tester; | 93 base::HistogramTester histogram_tester; |
| 60 histogram_tester.ExpectTotalCount("NQE.PeakKbps.Unknown", 0); | 94 histogram_tester.ExpectTotalCount("NQE.PeakKbps.Unknown", 0); |
| 61 histogram_tester.ExpectTotalCount("NQE.FastestRTT.Unknown", 0); | 95 histogram_tester.ExpectTotalCount("NQE.FastestRTT.Unknown", 0); |
| 62 | 96 |
| 63 estimator.OnConnectionTypeChanged( | 97 estimator.OnConnectionTypeChanged( |
| 64 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI); | 98 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI); |
| 65 histogram_tester.ExpectTotalCount("NQE.PeakKbps.Unknown", 1); | 99 histogram_tester.ExpectTotalCount("NQE.PeakKbps.Unknown", 1); |
| 66 histogram_tester.ExpectTotalCount("NQE.FastestRTT.Unknown", 1); | 100 histogram_tester.ExpectTotalCount("NQE.FastestRTT.Unknown", 1); |
| 67 { | 101 { |
| 68 NetworkQuality network_quality = estimator.GetPeakEstimate(); | 102 NetworkQuality network_quality = estimator.GetPeakEstimate(); |
| 69 EXPECT_EQ(estimator.current_connection_type_, | 103 EXPECT_EQ(estimator.current_network_id_.type, |
| 70 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI); | 104 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI); |
| 71 EXPECT_EQ(network_quality.rtt(), base::TimeDelta::Max()); | 105 EXPECT_EQ(network_quality.rtt(), base::TimeDelta::Max()); |
| 72 EXPECT_EQ(network_quality.downstream_throughput_kbps(), 0); | 106 EXPECT_EQ(network_quality.downstream_throughput_kbps(), 0); |
| 73 } | 107 } |
| 74 } | 108 } |
| 75 | 109 |
| 76 TEST(NetworkQualityEstimatorTest, StoreObservations) { | 110 TEST(NetworkQualityEstimatorTest, StoreObservations) { |
| 77 net::test_server::EmbeddedTestServer embedded_test_server; | 111 net::test_server::EmbeddedTestServer embedded_test_server; |
| 78 embedded_test_server.ServeFilesFromDirectory( | 112 embedded_test_server.ServeFilesFromDirectory( |
| 79 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); | 113 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 112 base::RunLoop().Run(); | 146 base::RunLoop().Run(); |
| 113 estimator.NotifyDataReceived(*request, std::numeric_limits<int64_t>::max(), | 147 estimator.NotifyDataReceived(*request, std::numeric_limits<int64_t>::max(), |
| 114 std::numeric_limits<int64_t>::max()); | 148 std::numeric_limits<int64_t>::max()); |
| 115 { | 149 { |
| 116 NetworkQuality network_quality = estimator.GetPeakEstimate(); | 150 NetworkQuality network_quality = estimator.GetPeakEstimate(); |
| 117 EXPECT_EQ(std::numeric_limits<int32_t>::max() - 1, | 151 EXPECT_EQ(std::numeric_limits<int32_t>::max() - 1, |
| 118 network_quality.downstream_throughput_kbps()); | 152 network_quality.downstream_throughput_kbps()); |
| 119 } | 153 } |
| 120 } | 154 } |
| 121 | 155 |
| 156 // Test if the network estimates are cached when network change notification |
| 157 // is invoked. |
| 158 TEST(NetworkQualityEstimatorTest, TestCaching) { |
| 159 TestNetworkQualityEstimator estimator; |
| 160 size_t expected_cache_size = 0; |
| 161 EXPECT_EQ(expected_cache_size, |
| 162 estimator.GetNetworkQualityCacheSizeForTests()); |
| 163 |
| 164 // Cache entry will be added for (NONE, ""). |
| 165 estimator.SimulateNetworkChangeTo( |
| 166 NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test-1"); |
| 167 EXPECT_EQ(++expected_cache_size, |
| 168 estimator.GetNetworkQualityCacheSizeForTests()); |
| 169 |
| 170 // Entry will be added for (2G, "test1"). |
| 171 // Also, set the network quality for (2G, "test1") so that it is stored in |
| 172 // the cache. |
| 173 estimator.peak_kbps_since_last_connection_change_ = 1; |
| 174 estimator.fastest_rtt_since_last_connection_change_ = |
| 175 base::TimeDelta::FromMilliseconds(1000); |
| 176 estimator.SimulateNetworkChangeTo( |
| 177 NetworkChangeNotifier::ConnectionType::CONNECTION_3G, "test-1"); |
| 178 EXPECT_EQ(++expected_cache_size, |
| 179 estimator.GetNetworkQualityCacheSizeForTests()); |
| 180 |
| 181 // Entry will be added for (3G, "test1"). |
| 182 // Also, set the network quality for (3G, "test1") so that it is stored in |
| 183 // the |
| 184 // cache. |
| 185 estimator.peak_kbps_since_last_connection_change_ = 2; |
| 186 estimator.fastest_rtt_since_last_connection_change_ = |
| 187 base::TimeDelta::FromMilliseconds(500); |
| 188 estimator.SimulateNetworkChangeTo( |
| 189 NetworkChangeNotifier::ConnectionType::CONNECTION_3G, "test-2"); |
| 190 EXPECT_EQ(++expected_cache_size, |
| 191 estimator.GetNetworkQualityCacheSizeForTests()); |
| 192 |
| 193 // Entry will be added for (3G, "test2"). |
| 194 estimator.SimulateNetworkChangeTo( |
| 195 NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test-1"); |
| 196 EXPECT_EQ(++expected_cache_size, |
| 197 estimator.GetNetworkQualityCacheSizeForTests()); |
| 198 |
| 199 // Read the network quality for (2G, "test-1"). |
| 200 EXPECT_TRUE(estimator.ReadCachedNetworkQualityEstimate()); |
| 201 EXPECT_EQ(1, estimator.peak_kbps_since_last_connection_change_); |
| 202 EXPECT_EQ(base::TimeDelta::FromMilliseconds(1000), |
| 203 estimator.fastest_rtt_since_last_connection_change_); |
| 204 // No new entry should be added for (2G, "test1") since it already exists |
| 205 // in the cache. |
| 206 estimator.SimulateNetworkChangeTo( |
| 207 NetworkChangeNotifier::ConnectionType::CONNECTION_3G, "test-1"); |
| 208 EXPECT_EQ(expected_cache_size, |
| 209 estimator.GetNetworkQualityCacheSizeForTests()); |
| 210 |
| 211 // Read the network quality for (3G, "test1"). |
| 212 EXPECT_TRUE(estimator.ReadCachedNetworkQualityEstimate()); |
| 213 EXPECT_EQ(2, estimator.peak_kbps_since_last_connection_change_); |
| 214 EXPECT_EQ(base::TimeDelta::FromMilliseconds(500), |
| 215 estimator.fastest_rtt_since_last_connection_change_); |
| 216 // No new entry should be added for (3G, "test1") since it already exists |
| 217 // in the cache. |
| 218 estimator.SimulateNetworkChangeTo( |
| 219 NetworkChangeNotifier::ConnectionType::CONNECTION_3G, "test-2"); |
| 220 EXPECT_EQ(expected_cache_size, |
| 221 estimator.GetNetworkQualityCacheSizeForTests()); |
| 222 |
| 223 // Reading quality of (3G, "test2") should return true. |
| 224 EXPECT_TRUE(estimator.ReadCachedNetworkQualityEstimate()); |
| 225 EXPECT_EQ(0, estimator.peak_kbps_since_last_connection_change_); |
| 226 EXPECT_EQ(base::TimeDelta::Max(), |
| 227 estimator.fastest_rtt_since_last_connection_change_); |
| 228 |
| 229 // Reading quality of (2G, "test-3") should return false. |
| 230 estimator.SimulateNetworkChangeTo( |
| 231 NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test-3"); |
| 232 EXPECT_FALSE(estimator.ReadCachedNetworkQualityEstimate()); |
| 233 } |
| 234 |
| 235 // Tests if the cache size remains bounded. Also, ensure that the cache is |
| 236 // LRU. |
| 237 TEST(NetworkQualityEstimatorTest, TestLRUCacheMaximumSize) { |
| 238 TestNetworkQualityEstimator estimator; |
| 239 estimator.SimulateNetworkChangeTo( |
| 240 net::NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, |
| 241 std::string()); |
| 242 EXPECT_EQ(1U, estimator.GetNetworkQualityCacheSizeForTests()); |
| 243 |
| 244 char network_name[20]; |
| 245 // Add 100 more networks than the maximum size of the cache. |
| 246 size_t network_count = |
| 247 NetworkQualityEstimator::kMaximumNetworkQualityCacheSize + 100; |
| 248 |
| 249 for (size_t i = 0; i < network_count; ++i) { |
| 250 base::strings::SafeSPrintf(network_name, "%d", i); |
| 251 estimator.SimulateNetworkChangeTo( |
| 252 net::NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, |
| 253 network_name); |
| 254 EXPECT_LE(estimator.GetNetworkQualityCacheSizeForTests(), |
| 255 NetworkQualityEstimator::kMaximumNetworkQualityCacheSize) |
| 256 << i; |
| 257 } |
| 258 // One more call so that the last network is also written to cache. |
| 259 estimator.SimulateNetworkChangeTo( |
| 260 net::NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, |
| 261 network_name); |
| 262 |
| 263 EXPECT_EQ(NetworkQualityEstimator::kMaximumNetworkQualityCacheSize, |
| 264 estimator.GetNetworkQualityCacheSizeForTests()); |
| 265 |
| 266 // Test that the cache is LRU by examining its contents. |
| 267 for (size_t i = 0; i < network_count; ++i) { |
| 268 // The first 100 networks should not be present in the cache. |
| 269 bool expect_present_in_cache = i >= 100; |
| 270 base::strings::SafeSPrintf(network_name, "%d", i); |
| 271 |
| 272 NetworkQualityEstimator::NetworkID network_id( |
| 273 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, network_name); |
| 274 |
| 275 bool found = estimator.cached_network_qualities_.find(network_id) != |
| 276 estimator.cached_network_qualities_.end(); |
| 277 EXPECT_EQ(expect_present_in_cache, found) << i; |
| 278 } |
| 279 } |
| 280 |
| 122 } // namespace net | 281 } // namespace net |
| OLD | NEW |