| 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 <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <limits> | 9 #include <limits> |
| 10 #include <map> | 10 #include <map> |
| 11 | 11 |
| 12 #include "base/basictypes.h" | 12 #include "base/basictypes.h" |
| 13 #include "base/files/file_path.h" | |
| 14 #include "base/logging.h" | 13 #include "base/logging.h" |
| 15 #include "base/memory/scoped_ptr.h" | 14 #include "base/memory/scoped_ptr.h" |
| 16 #include "base/metrics/histogram_samples.h" | 15 #include "base/metrics/histogram_samples.h" |
| 17 #include "base/run_loop.h" | 16 #include "base/run_loop.h" |
| 18 #include "base/strings/string_number_conversions.h" | 17 #include "base/strings/string_number_conversions.h" |
| 19 #include "base/test/histogram_tester.h" | 18 #include "base/test/histogram_tester.h" |
| 20 #include "base/time/time.h" | 19 #include "base/time/time.h" |
| 21 #include "build/build_config.h" | 20 #include "build/build_config.h" |
| 22 #include "net/base/external_estimate_provider.h" | 21 #include "net/base/external_estimate_provider.h" |
| 23 #include "net/base/load_flags.h" | 22 #include "net/base/load_flags.h" |
| 24 #include "net/base/network_change_notifier.h" | 23 #include "net/base/network_change_notifier.h" |
| 25 #include "net/http/http_status_code.h" | |
| 26 #include "net/test/embedded_test_server/embedded_test_server.h" | 24 #include "net/test/embedded_test_server/embedded_test_server.h" |
| 27 #include "net/test/embedded_test_server/http_request.h" | |
| 28 #include "net/test/embedded_test_server/http_response.h" | |
| 29 #include "net/url_request/url_request_test_util.h" | 25 #include "net/url_request/url_request_test_util.h" |
| 30 #include "testing/gtest/include/gtest/gtest.h" | 26 #include "testing/gtest/include/gtest/gtest.h" |
| 31 #include "url/gurl.h" | 27 #include "url/gurl.h" |
| 32 | 28 |
| 33 namespace { | 29 namespace { |
| 34 | 30 |
| 35 // Helps in setting the current network type and id. | 31 // Helps in setting the current network type and id. |
| 36 class TestNetworkQualityEstimator : public net::NetworkQualityEstimator { | 32 class TestNetworkQualityEstimator : public net::NetworkQualityEstimator { |
| 37 public: | 33 public: |
| 38 TestNetworkQualityEstimator( | 34 TestNetworkQualityEstimator( |
| 39 const std::map<std::string, std::string>& variation_params, | 35 const std::map<std::string, std::string>& variation_params) |
| 40 scoped_ptr<net::ExternalEstimateProvider> external_estimate_provider) | 36 : NetworkQualityEstimator(scoped_ptr<net::ExternalEstimateProvider>(), |
| 41 : NetworkQualityEstimator(external_estimate_provider.Pass(), | |
| 42 variation_params, | 37 variation_params, |
| 43 true, | 38 true, |
| 44 true) { | 39 true) {} |
| 45 // Set up embedded test server. | |
| 46 embedded_test_server_.ServeFilesFromDirectory( | |
| 47 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); | |
| 48 DCHECK(embedded_test_server_.InitializeAndWaitUntilReady()); | |
| 49 embedded_test_server_.RegisterRequestHandler(base::Bind( | |
| 50 &TestNetworkQualityEstimator::HandleRequest, base::Unretained(this))); | |
| 51 } | |
| 52 | |
| 53 explicit TestNetworkQualityEstimator( | |
| 54 const std::map<std::string, std::string>& variation_params) | |
| 55 : TestNetworkQualityEstimator( | |
| 56 variation_params, | |
| 57 scoped_ptr<net::ExternalEstimateProvider>()) {} | |
| 58 | 40 |
| 59 ~TestNetworkQualityEstimator() override {} | 41 ~TestNetworkQualityEstimator() override {} |
| 60 | 42 |
| 61 // Overrides the current network type and id. | 43 // Overrides the current network type and id. |
| 62 // Notifies network quality estimator of change in connection. | 44 // Notifies network quality estimator of change in connection. |
| 63 void SimulateNetworkChangeTo(net::NetworkChangeNotifier::ConnectionType type, | 45 void SimulateNetworkChangeTo(net::NetworkChangeNotifier::ConnectionType type, |
| 64 std::string network_id) { | 46 std::string network_id) { |
| 65 current_network_type_ = type; | 47 current_network_type_ = type; |
| 66 current_network_id_ = network_id; | 48 current_network_id_ = network_id; |
| 67 OnConnectionTypeChanged(type); | 49 OnConnectionTypeChanged(type); |
| 68 } | 50 } |
| 69 | 51 |
| 70 // Called by embedded server when a HTTP request is received. | |
| 71 scoped_ptr<net::test_server::HttpResponse> HandleRequest( | |
| 72 const net::test_server::HttpRequest& request) { | |
| 73 scoped_ptr<net::test_server::BasicHttpResponse> http_response( | |
| 74 new net::test_server::BasicHttpResponse()); | |
| 75 http_response->set_code(net::HTTP_OK); | |
| 76 http_response->set_content("hello"); | |
| 77 http_response->set_content_type("text/plain"); | |
| 78 return http_response.Pass(); | |
| 79 } | |
| 80 | |
| 81 // Returns a GURL hosted at embedded test server. | |
| 82 const GURL GetEchoURL() const { | |
| 83 return embedded_test_server_.GetURL("/echo.html"); | |
| 84 } | |
| 85 | |
| 86 using NetworkQualityEstimator::ReadCachedNetworkQualityEstimate; | 52 using NetworkQualityEstimator::ReadCachedNetworkQualityEstimate; |
| 87 using NetworkQualityEstimator::OnConnectionTypeChanged; | 53 using NetworkQualityEstimator::OnConnectionTypeChanged; |
| 88 | 54 |
| 89 private: | 55 private: |
| 90 // NetworkQualityEstimator implementation that returns the overridden network | 56 // NetworkQualityEstimator implementation that returns the overridden network |
| 91 // id (instead of invoking platform APIs). | 57 // id (instead of invoking platform APIs). |
| 92 NetworkQualityEstimator::NetworkID GetCurrentNetworkID() const override { | 58 NetworkQualityEstimator::NetworkID GetCurrentNetworkID() const override { |
| 93 return NetworkQualityEstimator::NetworkID(current_network_type_, | 59 return NetworkQualityEstimator::NetworkID(current_network_type_, |
| 94 current_network_id_); | 60 current_network_id_); |
| 95 } | 61 } |
| 96 | 62 |
| 97 net::NetworkChangeNotifier::ConnectionType current_network_type_; | 63 net::NetworkChangeNotifier::ConnectionType current_network_type_; |
| 98 std::string current_network_id_; | 64 std::string current_network_id_; |
| 99 | |
| 100 // Embedded server used for testing. | |
| 101 net::test_server::EmbeddedTestServer embedded_test_server_; | |
| 102 | |
| 103 DISALLOW_COPY_AND_ASSIGN(TestNetworkQualityEstimator); | |
| 104 }; | 65 }; |
| 105 | 66 |
| 106 } // namespace | 67 } // namespace |
| 107 | 68 |
| 108 namespace net { | 69 namespace net { |
| 109 | 70 |
| 110 TEST(NetworkQualityEstimatorTest, TestKbpsRTTUpdates) { | 71 TEST(NetworkQualityEstimatorTest, TestKbpsRTTUpdates) { |
| 72 net::test_server::EmbeddedTestServer embedded_test_server; |
| 73 embedded_test_server.ServeFilesFromDirectory( |
| 74 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); |
| 75 ASSERT_TRUE(embedded_test_server.InitializeAndWaitUntilReady()); |
| 76 |
| 111 base::HistogramTester histogram_tester; | 77 base::HistogramTester histogram_tester; |
| 112 // Enable requests to local host to be used for network quality estimation. | 78 // Enable requests to local host to be used for network quality estimation. |
| 113 std::map<std::string, std::string> variation_params; | 79 std::map<std::string, std::string> variation_params; |
| 114 TestNetworkQualityEstimator estimator(variation_params); | 80 TestNetworkQualityEstimator estimator(variation_params); |
| 115 | 81 |
| 116 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(), | 82 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(), |
| 117 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); | 83 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); |
| 118 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput, | 84 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput, |
| 119 estimator.GetDownlinkThroughputKbpsEstimateInternal( | 85 estimator.GetDownlinkThroughputKbpsEstimateInternal( |
| 120 base::TimeTicks(), 100)); | 86 base::TimeTicks(), 100)); |
| 121 | 87 |
| 122 TestDelegate test_delegate; | 88 TestDelegate test_delegate; |
| 123 TestURLRequestContext context(true); | 89 TestURLRequestContext context(false); |
| 124 context.set_network_quality_estimator(&estimator); | |
| 125 context.Init(); | |
| 126 | 90 |
| 127 scoped_ptr<URLRequest> request(context.CreateRequest( | 91 scoped_ptr<URLRequest> request( |
| 128 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); | 92 context.CreateRequest(embedded_test_server.GetURL("/echo.html"), |
| 93 DEFAULT_PRIORITY, &test_delegate)); |
| 129 request->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME); | 94 request->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME); |
| 130 request->Start(); | 95 request->Start(); |
| 96 |
| 131 base::RunLoop().Run(); | 97 base::RunLoop().Run(); |
| 132 | 98 |
| 133 // Both RTT and downstream throughput should be updated. | 99 // Both RTT and downstream throughput should be updated. |
| 100 estimator.NotifyHeadersReceived(*request); |
| 101 estimator.NotifyRequestCompleted(*request); |
| 134 EXPECT_NE(NetworkQualityEstimator::InvalidRTT(), | 102 EXPECT_NE(NetworkQualityEstimator::InvalidRTT(), |
| 135 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); | 103 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); |
| 136 EXPECT_NE(NetworkQualityEstimator::kInvalidThroughput, | 104 EXPECT_NE(NetworkQualityEstimator::kInvalidThroughput, |
| 137 estimator.GetDownlinkThroughputKbpsEstimateInternal( | 105 estimator.GetDownlinkThroughputKbpsEstimateInternal( |
| 138 base::TimeTicks(), 100)); | 106 base::TimeTicks(), 100)); |
| 139 | 107 |
| 140 base::TimeDelta rtt = NetworkQualityEstimator::InvalidRTT(); | 108 base::TimeDelta rtt = NetworkQualityEstimator::InvalidRTT(); |
| 141 int32_t kbps = NetworkQualityEstimator::kInvalidThroughput; | 109 int32_t kbps = NetworkQualityEstimator::kInvalidThroughput; |
| 142 EXPECT_TRUE(estimator.GetRTTEstimate(&rtt)); | 110 EXPECT_TRUE(estimator.GetRTTEstimate(&rtt)); |
| 143 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); | 111 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); |
| 144 EXPECT_NE(NetworkQualityEstimator::InvalidRTT(), rtt); | 112 EXPECT_NE(NetworkQualityEstimator::InvalidRTT(), rtt); |
| 145 EXPECT_NE(NetworkQualityEstimator::kInvalidThroughput, kbps); | 113 EXPECT_NE(NetworkQualityEstimator::kInvalidThroughput, kbps); |
| 146 | 114 |
| 147 EXPECT_NEAR( | 115 EXPECT_NEAR( |
| 148 rtt.InMilliseconds(), | 116 rtt.InMilliseconds(), |
| 149 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100).InMilliseconds(), | 117 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100).InMilliseconds(), |
| 150 1); | 118 1); |
| 151 | 119 |
| 152 // Check UMA histograms. | 120 // Check UMA histograms. |
| 153 histogram_tester.ExpectTotalCount("NQE.PeakKbps.Unknown", 0); | 121 histogram_tester.ExpectTotalCount("NQE.PeakKbps.Unknown", 0); |
| 154 histogram_tester.ExpectTotalCount("NQE.FastestRTT.Unknown", 0); | 122 histogram_tester.ExpectTotalCount("NQE.FastestRTT.Unknown", 0); |
| 155 | 123 |
| 156 histogram_tester.ExpectTotalCount("NQE.RatioEstimatedToActualRTT.Unknown", 0); | 124 histogram_tester.ExpectTotalCount("NQE.RatioEstimatedToActualRTT.Unknown", 0); |
| 157 | 125 |
| 158 scoped_ptr<URLRequest> request2(context.CreateRequest( | 126 estimator.NotifyHeadersReceived(*request); |
| 159 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); | 127 estimator.NotifyRequestCompleted(*request); |
| 160 request2->SetLoadFlags(request2->load_flags() | LOAD_MAIN_FRAME); | |
| 161 request2->Start(); | |
| 162 base::RunLoop().Run(); | |
| 163 | |
| 164 histogram_tester.ExpectTotalCount("NQE.RTTObservations.Unknown", 1); | 128 histogram_tester.ExpectTotalCount("NQE.RTTObservations.Unknown", 1); |
| 165 estimator.SimulateNetworkChangeTo( | 129 estimator.SimulateNetworkChangeTo( |
| 166 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test-1"); | 130 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test-1"); |
| 167 histogram_tester.ExpectTotalCount("NQE.PeakKbps.Unknown", 1); | 131 histogram_tester.ExpectTotalCount("NQE.PeakKbps.Unknown", 1); |
| 168 histogram_tester.ExpectTotalCount("NQE.FastestRTT.Unknown", 1); | 132 histogram_tester.ExpectTotalCount("NQE.FastestRTT.Unknown", 1); |
| 169 | 133 |
| 170 histogram_tester.ExpectTotalCount("NQE.RatioMedianRTT.WiFi", 0); | 134 histogram_tester.ExpectTotalCount("NQE.RatioMedianRTT.WiFi", 0); |
| 171 | 135 |
| 172 histogram_tester.ExpectTotalCount("NQE.RTT.Percentile0.Unknown", 1); | 136 histogram_tester.ExpectTotalCount("NQE.RTT.Percentile0.Unknown", 1); |
| 173 histogram_tester.ExpectTotalCount("NQE.RTT.Percentile10.Unknown", 1); | 137 histogram_tester.ExpectTotalCount("NQE.RTT.Percentile10.Unknown", 1); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 195 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); | 159 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); |
| 196 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput, | 160 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput, |
| 197 estimator.GetDownlinkThroughputKbpsEstimateInternal( | 161 estimator.GetDownlinkThroughputKbpsEstimateInternal( |
| 198 base::TimeTicks(), 100)); | 162 base::TimeTicks(), 100)); |
| 199 | 163 |
| 200 EXPECT_FALSE(estimator.GetRTTEstimate(&rtt)); | 164 EXPECT_FALSE(estimator.GetRTTEstimate(&rtt)); |
| 201 EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); | 165 EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); |
| 202 } | 166 } |
| 203 | 167 |
| 204 TEST(NetworkQualityEstimatorTest, StoreObservations) { | 168 TEST(NetworkQualityEstimatorTest, StoreObservations) { |
| 169 net::test_server::EmbeddedTestServer embedded_test_server; |
| 170 embedded_test_server.ServeFilesFromDirectory( |
| 171 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); |
| 172 ASSERT_TRUE(embedded_test_server.InitializeAndWaitUntilReady()); |
| 173 |
| 205 std::map<std::string, std::string> variation_params; | 174 std::map<std::string, std::string> variation_params; |
| 206 TestNetworkQualityEstimator estimator(variation_params); | 175 TestNetworkQualityEstimator estimator(variation_params); |
| 207 | |
| 208 TestDelegate test_delegate; | 176 TestDelegate test_delegate; |
| 209 TestURLRequestContext context(true); | 177 TestURLRequestContext context(false); |
| 210 context.set_network_quality_estimator(&estimator); | |
| 211 context.Init(); | |
| 212 | 178 |
| 213 // Push 10 more observations than the maximum buffer size. | 179 // Push 10 more observations than the maximum buffer size. |
| 214 for (size_t i = 0; i < estimator.kMaximumObservationsBufferSize + 10U; ++i) { | 180 for (size_t i = 0; i < estimator.kMaximumObservationsBufferSize + 10U; ++i) { |
| 215 scoped_ptr<URLRequest> request(context.CreateRequest( | 181 scoped_ptr<URLRequest> request( |
| 216 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); | 182 context.CreateRequest(embedded_test_server.GetURL("/echo.html"), |
| 183 DEFAULT_PRIORITY, &test_delegate)); |
| 217 request->Start(); | 184 request->Start(); |
| 218 base::RunLoop().Run(); | 185 base::RunLoop().Run(); |
| 186 |
| 187 estimator.NotifyHeadersReceived(*request); |
| 188 estimator.NotifyRequestCompleted(*request); |
| 219 } | 189 } |
| 220 | 190 |
| 221 EXPECT_EQ(static_cast<size_t>( | 191 EXPECT_EQ(static_cast<size_t>( |
| 222 NetworkQualityEstimator::kMaximumObservationsBufferSize), | 192 NetworkQualityEstimator::kMaximumObservationsBufferSize), |
| 223 estimator.downstream_throughput_kbps_observations_.Size()); | 193 estimator.downstream_throughput_kbps_observations_.Size()); |
| 224 EXPECT_EQ(static_cast<size_t>( | 194 EXPECT_EQ(static_cast<size_t>( |
| 225 NetworkQualityEstimator::kMaximumObservationsBufferSize), | 195 NetworkQualityEstimator::kMaximumObservationsBufferSize), |
| 226 estimator.rtt_msec_observations_.Size()); | 196 estimator.rtt_msec_observations_.Size()); |
| 227 | 197 |
| 228 // Verify that the stored observations are cleared on network change. | 198 // Verify that the stored observations are cleared on network change. |
| 229 estimator.SimulateNetworkChangeTo( | 199 estimator.SimulateNetworkChangeTo( |
| 230 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test-2"); | 200 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test-2"); |
| 231 EXPECT_EQ(0U, estimator.downstream_throughput_kbps_observations_.Size()); | 201 EXPECT_EQ(0U, estimator.downstream_throughput_kbps_observations_.Size()); |
| 232 EXPECT_EQ(0U, estimator.rtt_msec_observations_.Size()); | 202 EXPECT_EQ(0U, estimator.rtt_msec_observations_.Size()); |
| 203 |
| 204 scoped_ptr<URLRequest> request( |
| 205 context.CreateRequest(embedded_test_server.GetURL("/echo.html"), |
| 206 DEFAULT_PRIORITY, &test_delegate)); |
| 233 } | 207 } |
| 234 | 208 |
| 235 // Verifies that the percentiles are correctly computed. All observations have | 209 // Verifies that the percentiles are correctly computed. All observations have |
| 236 // the same timestamp. Kbps percentiles must be in decreasing order. RTT | 210 // the same timestamp. Kbps percentiles must be in decreasing order. RTT |
| 237 // percentiles must be in increasing order. | 211 // percentiles must be in increasing order. |
| 238 TEST(NetworkQualityEstimatorTest, PercentileSameTimestamps) { | 212 TEST(NetworkQualityEstimatorTest, PercentileSameTimestamps) { |
| 239 std::map<std::string, std::string> variation_params; | 213 std::map<std::string, std::string> variation_params; |
| 240 TestNetworkQualityEstimator estimator(variation_params); | 214 TestNetworkQualityEstimator estimator(variation_params); |
| 241 base::TimeTicks now = base::TimeTicks::Now(); | 215 base::TimeTicks now = base::TimeTicks::Now(); |
| 242 | 216 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 335 base::TimeTicks::Now() + base::TimeDelta::FromMinutes(10), 50)); | 309 base::TimeTicks::Now() + base::TimeDelta::FromMinutes(10), 50)); |
| 336 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput, | 310 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput, |
| 337 estimator.GetDownlinkThroughputKbpsEstimateInternal( | 311 estimator.GetDownlinkThroughputKbpsEstimateInternal( |
| 338 base::TimeTicks::Now() + base::TimeDelta::FromMinutes(10), 50)); | 312 base::TimeTicks::Now() + base::TimeDelta::FromMinutes(10), 50)); |
| 339 } | 313 } |
| 340 | 314 |
| 341 // This test notifies NetworkQualityEstimator of received data. Next, | 315 // This test notifies NetworkQualityEstimator of received data. Next, |
| 342 // throughput and RTT percentiles are checked for correctness by doing simple | 316 // throughput and RTT percentiles are checked for correctness by doing simple |
| 343 // verifications. | 317 // verifications. |
| 344 TEST(NetworkQualityEstimatorTest, ComputedPercentiles) { | 318 TEST(NetworkQualityEstimatorTest, ComputedPercentiles) { |
| 319 net::test_server::EmbeddedTestServer embedded_test_server; |
| 320 embedded_test_server.ServeFilesFromDirectory( |
| 321 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); |
| 322 ASSERT_TRUE(embedded_test_server.InitializeAndWaitUntilReady()); |
| 323 |
| 345 std::map<std::string, std::string> variation_params; | 324 std::map<std::string, std::string> variation_params; |
| 346 TestNetworkQualityEstimator estimator(variation_params); | 325 TestNetworkQualityEstimator estimator(variation_params); |
| 347 | 326 |
| 348 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(), | 327 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(), |
| 349 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); | 328 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); |
| 350 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput, | 329 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput, |
| 351 estimator.GetDownlinkThroughputKbpsEstimateInternal( | 330 estimator.GetDownlinkThroughputKbpsEstimateInternal( |
| 352 base::TimeTicks(), 100)); | 331 base::TimeTicks(), 100)); |
| 353 | 332 |
| 354 TestDelegate test_delegate; | 333 TestDelegate test_delegate; |
| 355 TestURLRequestContext context(true); | 334 TestURLRequestContext context(false); |
| 356 context.set_network_quality_estimator(&estimator); | |
| 357 context.Init(); | |
| 358 | 335 |
| 359 // Number of observations are more than the maximum buffer size. | 336 // Number of observations are more than the maximum buffer size. |
| 360 for (size_t i = 0; i < estimator.kMaximumObservationsBufferSize + 100U; ++i) { | 337 for (size_t i = 0; i < estimator.kMaximumObservationsBufferSize + 100U; ++i) { |
| 361 scoped_ptr<URLRequest> request(context.CreateRequest( | 338 scoped_ptr<URLRequest> request( |
| 362 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); | 339 context.CreateRequest(embedded_test_server.GetURL("/echo.html"), |
| 340 DEFAULT_PRIORITY, &test_delegate)); |
| 363 request->Start(); | 341 request->Start(); |
| 364 base::RunLoop().Run(); | 342 base::RunLoop().Run(); |
| 343 |
| 344 // Use different number of bytes to create variation. |
| 345 estimator.NotifyHeadersReceived(*request); |
| 346 estimator.NotifyRequestCompleted(*request); |
| 365 } | 347 } |
| 366 | 348 |
| 367 // Verify the percentiles through simple tests. | 349 // Verify the percentiles through simple tests. |
| 368 for (int i = 0; i <= 100; ++i) { | 350 for (int i = 0; i <= 100; ++i) { |
| 369 EXPECT_GT(estimator.GetDownlinkThroughputKbpsEstimateInternal( | 351 EXPECT_GT(estimator.GetDownlinkThroughputKbpsEstimateInternal( |
| 370 base::TimeTicks(), i), | 352 base::TimeTicks(), i), |
| 371 0); | 353 0); |
| 372 EXPECT_LT(estimator.GetRTTEstimateInternal(base::TimeTicks(), i), | 354 EXPECT_LT(estimator.GetRTTEstimateInternal(base::TimeTicks(), i), |
| 373 base::TimeDelta::Max()); | 355 base::TimeDelta::Max()); |
| 374 | 356 |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 665 EXPECT_EQ(100, rtt.InMilliseconds()); | 647 EXPECT_EQ(100, rtt.InMilliseconds()); |
| 666 | 648 |
| 667 int32_t downstream_throughput_kbps; | 649 int32_t downstream_throughput_kbps; |
| 668 EXPECT_FALSE(estimator.GetRecentMedianDownlinkThroughputKbps( | 650 EXPECT_FALSE(estimator.GetRecentMedianDownlinkThroughputKbps( |
| 669 now + base::TimeDelta::FromSeconds(10), &downstream_throughput_kbps)); | 651 now + base::TimeDelta::FromSeconds(10), &downstream_throughput_kbps)); |
| 670 EXPECT_TRUE(estimator.GetRecentMedianDownlinkThroughputKbps( | 652 EXPECT_TRUE(estimator.GetRecentMedianDownlinkThroughputKbps( |
| 671 now, &downstream_throughput_kbps)); | 653 now, &downstream_throughput_kbps)); |
| 672 EXPECT_EQ(100, downstream_throughput_kbps); | 654 EXPECT_EQ(100, downstream_throughput_kbps); |
| 673 } | 655 } |
| 674 | 656 |
| 675 // An external estimate provider that does not have a valid RTT or throughput | |
| 676 // estimate. | |
| 677 class InvalidExternalEstimateProvider : public ExternalEstimateProvider { | |
| 678 public: | |
| 679 InvalidExternalEstimateProvider() : get_rtt_count_(0) {} | |
| 680 ~InvalidExternalEstimateProvider() override {} | |
| 681 | |
| 682 // ExternalEstimateProvider implementation: | |
| 683 bool GetRTT(base::TimeDelta* rtt) const override { | |
| 684 DCHECK(rtt); | |
| 685 get_rtt_count_++; | |
| 686 return false; | |
| 687 } | |
| 688 | |
| 689 // ExternalEstimateProvider implementation: | |
| 690 bool GetDownstreamThroughputKbps( | |
| 691 int32_t* downstream_throughput_kbps) const override { | |
| 692 DCHECK(downstream_throughput_kbps); | |
| 693 return false; | |
| 694 } | |
| 695 | |
| 696 // ExternalEstimateProvider implementation: | |
| 697 bool GetUpstreamThroughputKbps( | |
| 698 int32_t* upstream_throughput_kbps) const override { | |
| 699 // NetworkQualityEstimator does not support upstream throughput. | |
| 700 ADD_FAILURE(); | |
| 701 return false; | |
| 702 } | |
| 703 | |
| 704 // ExternalEstimateProvider implementation: | |
| 705 bool GetTimeSinceLastUpdate( | |
| 706 base::TimeDelta* time_since_last_update) const override { | |
| 707 *time_since_last_update = base::TimeDelta::FromMilliseconds(1); | |
| 708 return true; | |
| 709 } | |
| 710 | |
| 711 // ExternalEstimateProvider implementation: | |
| 712 void SetUpdatedEstimateDelegate(UpdatedEstimateDelegate* delegate) override {} | |
| 713 | |
| 714 // ExternalEstimateProvider implementation: | |
| 715 void Update() const override {} | |
| 716 | |
| 717 size_t get_rtt_count() const { return get_rtt_count_; } | |
| 718 | |
| 719 private: | |
| 720 // Keeps track of number of times different functions were called. | |
| 721 mutable size_t get_rtt_count_; | |
| 722 | |
| 723 DISALLOW_COPY_AND_ASSIGN(InvalidExternalEstimateProvider); | |
| 724 }; | |
| 725 | |
| 726 // Tests if the RTT value from external estimate provider is discarded if the | |
| 727 // external estimate provider is invalid. | |
| 728 TEST(NetworkQualityEstimatorTest, InvalidExternalEstimateProvider) { | |
| 729 InvalidExternalEstimateProvider* invalid_external_estimate_provider = | |
| 730 new InvalidExternalEstimateProvider(); | |
| 731 scoped_ptr<ExternalEstimateProvider> external_estimate_provider( | |
| 732 invalid_external_estimate_provider); | |
| 733 | |
| 734 TestNetworkQualityEstimator estimator(std::map<std::string, std::string>(), | |
| 735 external_estimate_provider.Pass()); | |
| 736 | |
| 737 base::TimeDelta rtt; | |
| 738 int32_t kbps; | |
| 739 EXPECT_EQ(1U, invalid_external_estimate_provider->get_rtt_count()); | |
| 740 EXPECT_FALSE(estimator.GetRTTEstimate(&rtt)); | |
| 741 EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); | |
| 742 } | |
| 743 | |
| 744 class TestExternalEstimateProvider : public ExternalEstimateProvider { | |
| 745 public: | |
| 746 TestExternalEstimateProvider(base::TimeDelta rtt, | |
| 747 int32_t downstream_throughput_kbps) | |
| 748 : rtt_(rtt), | |
| 749 downstream_throughput_kbps_(downstream_throughput_kbps), | |
| 750 time_since_last_update_(base::TimeDelta::FromSeconds(1)), | |
| 751 get_time_since_last_update_count_(0), | |
| 752 get_rtt_count_(0), | |
| 753 get_downstream_throughput_kbps_count_(0), | |
| 754 update_count_(0) {} | |
| 755 ~TestExternalEstimateProvider() override {} | |
| 756 | |
| 757 // ExternalEstimateProvider implementation: | |
| 758 bool GetRTT(base::TimeDelta* rtt) const override { | |
| 759 *rtt = rtt_; | |
| 760 get_rtt_count_++; | |
| 761 return true; | |
| 762 } | |
| 763 | |
| 764 // ExternalEstimateProvider implementation: | |
| 765 bool GetDownstreamThroughputKbps( | |
| 766 int32_t* downstream_throughput_kbps) const override { | |
| 767 *downstream_throughput_kbps = downstream_throughput_kbps_; | |
| 768 get_downstream_throughput_kbps_count_++; | |
| 769 return true; | |
| 770 } | |
| 771 | |
| 772 // ExternalEstimateProvider implementation: | |
| 773 bool GetUpstreamThroughputKbps( | |
| 774 int32_t* upstream_throughput_kbps) const override { | |
| 775 // NetworkQualityEstimator does not support upstream throughput. | |
| 776 ADD_FAILURE(); | |
| 777 return false; | |
| 778 } | |
| 779 | |
| 780 // ExternalEstimateProvider implementation: | |
| 781 bool GetTimeSinceLastUpdate( | |
| 782 base::TimeDelta* time_since_last_update) const override { | |
| 783 *time_since_last_update = time_since_last_update_; | |
| 784 get_time_since_last_update_count_++; | |
| 785 return true; | |
| 786 } | |
| 787 | |
| 788 // ExternalEstimateProvider implementation: | |
| 789 void SetUpdatedEstimateDelegate(UpdatedEstimateDelegate* delegate) override {} | |
| 790 | |
| 791 // ExternalEstimateProvider implementation: | |
| 792 void Update() const override { update_count_++; } | |
| 793 | |
| 794 void set_time_since_last_update(base::TimeDelta time_since_last_update) { | |
| 795 time_since_last_update_ = time_since_last_update; | |
| 796 } | |
| 797 | |
| 798 size_t get_time_since_last_update_count() const { | |
| 799 return get_time_since_last_update_count_; | |
| 800 } | |
| 801 size_t get_rtt_count() const { return get_rtt_count_; } | |
| 802 size_t get_downstream_throughput_kbps_count() const { | |
| 803 return get_downstream_throughput_kbps_count_; | |
| 804 } | |
| 805 size_t update_count() const { return update_count_; } | |
| 806 | |
| 807 private: | |
| 808 // RTT and downstream throughput estimates. | |
| 809 const base::TimeDelta rtt_; | |
| 810 const int32_t downstream_throughput_kbps_; | |
| 811 | |
| 812 base::TimeDelta time_since_last_update_; | |
| 813 | |
| 814 // Keeps track of number of times different functions were called. | |
| 815 mutable size_t get_time_since_last_update_count_; | |
| 816 mutable size_t get_rtt_count_; | |
| 817 mutable size_t get_downstream_throughput_kbps_count_; | |
| 818 mutable size_t update_count_; | |
| 819 | |
| 820 DISALLOW_COPY_AND_ASSIGN(TestExternalEstimateProvider); | |
| 821 }; | |
| 822 | |
| 823 // Tests if the external estimate provider is called in the constructor and | |
| 824 // on network change notification. | |
| 825 TEST(NetworkQualityEstimatorTest, TestExternalEstimateProvider) { | |
| 826 TestExternalEstimateProvider* test_external_estimate_provider = | |
| 827 new TestExternalEstimateProvider(base::TimeDelta::FromMilliseconds(1), | |
| 828 100); | |
| 829 scoped_ptr<ExternalEstimateProvider> external_estimate_provider( | |
| 830 test_external_estimate_provider); | |
| 831 std::map<std::string, std::string> variation_params; | |
| 832 TestNetworkQualityEstimator estimator(variation_params, | |
| 833 external_estimate_provider.Pass()); | |
| 834 | |
| 835 base::TimeDelta rtt; | |
| 836 int32_t kbps; | |
| 837 EXPECT_TRUE(estimator.GetRTTEstimate(&rtt)); | |
| 838 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); | |
| 839 | |
| 840 EXPECT_EQ( | |
| 841 1U, test_external_estimate_provider->get_time_since_last_update_count()); | |
| 842 EXPECT_EQ(1U, test_external_estimate_provider->get_rtt_count()); | |
| 843 EXPECT_EQ( | |
| 844 1U, | |
| 845 test_external_estimate_provider->get_downstream_throughput_kbps_count()); | |
| 846 | |
| 847 // Change network type to WiFi. Number of queries to External estimate | |
| 848 // provider must increment. | |
| 849 estimator.SimulateNetworkChangeTo( | |
| 850 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test-1"); | |
| 851 EXPECT_TRUE(estimator.GetRTTEstimate(&rtt)); | |
| 852 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); | |
| 853 EXPECT_EQ( | |
| 854 2U, test_external_estimate_provider->get_time_since_last_update_count()); | |
| 855 EXPECT_EQ(2U, test_external_estimate_provider->get_rtt_count()); | |
| 856 EXPECT_EQ( | |
| 857 2U, | |
| 858 test_external_estimate_provider->get_downstream_throughput_kbps_count()); | |
| 859 | |
| 860 // Change network type to 2G. Number of queries to External estimate provider | |
| 861 // must increment. | |
| 862 estimator.SimulateNetworkChangeTo( | |
| 863 NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test-1"); | |
| 864 EXPECT_EQ( | |
| 865 3U, test_external_estimate_provider->get_time_since_last_update_count()); | |
| 866 EXPECT_EQ(3U, test_external_estimate_provider->get_rtt_count()); | |
| 867 EXPECT_EQ( | |
| 868 3U, | |
| 869 test_external_estimate_provider->get_downstream_throughput_kbps_count()); | |
| 870 | |
| 871 // Set the external estimate as old. Network Quality estimator should request | |
| 872 // an update on connection type change. | |
| 873 EXPECT_EQ(0U, test_external_estimate_provider->update_count()); | |
| 874 test_external_estimate_provider->set_time_since_last_update( | |
| 875 base::TimeDelta::Max()); | |
| 876 | |
| 877 estimator.SimulateNetworkChangeTo( | |
| 878 NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test-2"); | |
| 879 EXPECT_EQ( | |
| 880 4U, test_external_estimate_provider->get_time_since_last_update_count()); | |
| 881 EXPECT_EQ(3U, test_external_estimate_provider->get_rtt_count()); | |
| 882 EXPECT_EQ( | |
| 883 3U, | |
| 884 test_external_estimate_provider->get_downstream_throughput_kbps_count()); | |
| 885 EXPECT_EQ(1U, test_external_estimate_provider->update_count()); | |
| 886 | |
| 887 // Estimates are unavailable because external estimate provider never | |
| 888 // notifies network quality estimator of the updated estimates. | |
| 889 EXPECT_FALSE(estimator.GetRTTEstimate(&rtt)); | |
| 890 EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); | |
| 891 } | |
| 892 | |
| 893 // Tests if the estimate from the external estimate provider is merged with the | |
| 894 // observations collected from the HTTP requests. | |
| 895 TEST(NetworkQualityEstimatorTest, TestExternalEstimateProviderMergeEstimates) { | |
| 896 const base::TimeDelta external_estimate_provider_rtt = | |
| 897 base::TimeDelta::FromMilliseconds(1); | |
| 898 const int32_t external_estimate_provider_downstream_throughput = 100; | |
| 899 TestExternalEstimateProvider* test_external_estimate_provider = | |
| 900 new TestExternalEstimateProvider( | |
| 901 external_estimate_provider_rtt, | |
| 902 external_estimate_provider_downstream_throughput); | |
| 903 scoped_ptr<ExternalEstimateProvider> external_estimate_provider( | |
| 904 test_external_estimate_provider); | |
| 905 | |
| 906 std::map<std::string, std::string> variation_params; | |
| 907 TestNetworkQualityEstimator estimator(variation_params, | |
| 908 external_estimate_provider.Pass()); | |
| 909 | |
| 910 base::TimeDelta rtt; | |
| 911 // Estimate provided by network quality estimator should match the estimate | |
| 912 // provided by external estimate provider. | |
| 913 EXPECT_TRUE(estimator.GetRTTEstimate(&rtt)); | |
| 914 EXPECT_EQ(external_estimate_provider_rtt, rtt); | |
| 915 | |
| 916 int32_t kbps; | |
| 917 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); | |
| 918 EXPECT_EQ(external_estimate_provider_downstream_throughput, kbps); | |
| 919 | |
| 920 EXPECT_EQ(1U, estimator.rtt_msec_observations_.Size()); | |
| 921 EXPECT_EQ(1U, estimator.downstream_throughput_kbps_observations_.Size()); | |
| 922 | |
| 923 TestDelegate test_delegate; | |
| 924 TestURLRequestContext context(true); | |
| 925 context.set_network_quality_estimator(&estimator); | |
| 926 context.Init(); | |
| 927 | |
| 928 scoped_ptr<URLRequest> request(context.CreateRequest( | |
| 929 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); | |
| 930 request->Start(); | |
| 931 base::RunLoop().Run(); | |
| 932 | |
| 933 EXPECT_EQ(2U, estimator.rtt_msec_observations_.Size()); | |
| 934 EXPECT_EQ(2U, estimator.downstream_throughput_kbps_observations_.Size()); | |
| 935 } | |
| 936 | |
| 937 } // namespace net | 657 } // namespace net |
| OLD | NEW |