| 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" |
| 13 #include "base/logging.h" | 14 #include "base/logging.h" |
| 14 #include "base/memory/scoped_ptr.h" | 15 #include "base/memory/scoped_ptr.h" |
| 15 #include "base/metrics/histogram_samples.h" | 16 #include "base/metrics/histogram_samples.h" |
| 16 #include "base/run_loop.h" | 17 #include "base/run_loop.h" |
| 17 #include "base/strings/string_number_conversions.h" | 18 #include "base/strings/string_number_conversions.h" |
| 18 #include "base/test/histogram_tester.h" | 19 #include "base/test/histogram_tester.h" |
| 19 #include "base/time/time.h" | 20 #include "base/time/time.h" |
| 20 #include "build/build_config.h" | 21 #include "build/build_config.h" |
| 21 #include "net/base/external_estimate_provider.h" | 22 #include "net/base/external_estimate_provider.h" |
| 22 #include "net/base/load_flags.h" | 23 #include "net/base/load_flags.h" |
| 23 #include "net/base/network_change_notifier.h" | 24 #include "net/base/network_change_notifier.h" |
| 25 #include "net/http/http_status_code.h" |
| 24 #include "net/test/embedded_test_server/embedded_test_server.h" | 26 #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" |
| 25 #include "net/url_request/url_request_test_util.h" | 29 #include "net/url_request/url_request_test_util.h" |
| 26 #include "testing/gtest/include/gtest/gtest.h" | 30 #include "testing/gtest/include/gtest/gtest.h" |
| 27 #include "url/gurl.h" | 31 #include "url/gurl.h" |
| 28 | 32 |
| 29 namespace { | 33 namespace { |
| 30 | 34 |
| 31 // Helps in setting the current network type and id. | 35 // Helps in setting the current network type and id. |
| 32 class TestNetworkQualityEstimator : public net::NetworkQualityEstimator { | 36 class TestNetworkQualityEstimator : public net::NetworkQualityEstimator { |
| 33 public: | 37 public: |
| 34 TestNetworkQualityEstimator( | 38 TestNetworkQualityEstimator( |
| 35 const std::map<std::string, std::string>& variation_params) | 39 const std::map<std::string, std::string>& variation_params, |
| 36 : NetworkQualityEstimator(scoped_ptr<net::ExternalEstimateProvider>(), | 40 scoped_ptr<net::ExternalEstimateProvider> external_estimate_provider) |
| 41 : NetworkQualityEstimator(external_estimate_provider.Pass(), |
| 37 variation_params, | 42 variation_params, |
| 38 true, | 43 true, |
| 39 true) {} | 44 true) { |
| 45 // Set up embedded test server. |
| 46 embedded_test_server_.ServeFilesFromDirectory( |
| 47 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); |
| 48 EXPECT_TRUE(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>()) {} |
| 40 | 58 |
| 41 ~TestNetworkQualityEstimator() override {} | 59 ~TestNetworkQualityEstimator() override {} |
| 42 | 60 |
| 43 // Overrides the current network type and id. | 61 // Overrides the current network type and id. |
| 44 // Notifies network quality estimator of change in connection. | 62 // Notifies network quality estimator of change in connection. |
| 45 void SimulateNetworkChangeTo(net::NetworkChangeNotifier::ConnectionType type, | 63 void SimulateNetworkChangeTo(net::NetworkChangeNotifier::ConnectionType type, |
| 46 std::string network_id) { | 64 std::string network_id) { |
| 47 current_network_type_ = type; | 65 current_network_type_ = type; |
| 48 current_network_id_ = network_id; | 66 current_network_id_ = network_id; |
| 49 OnConnectionTypeChanged(type); | 67 OnConnectionTypeChanged(type); |
| 50 } | 68 } |
| 51 | 69 |
| 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 |
| 52 using NetworkQualityEstimator::ReadCachedNetworkQualityEstimate; | 86 using NetworkQualityEstimator::ReadCachedNetworkQualityEstimate; |
| 53 using NetworkQualityEstimator::OnConnectionTypeChanged; | 87 using NetworkQualityEstimator::OnConnectionTypeChanged; |
| 54 | 88 |
| 55 private: | 89 private: |
| 56 // NetworkQualityEstimator implementation that returns the overridden network | 90 // NetworkQualityEstimator implementation that returns the overridden network |
| 57 // id (instead of invoking platform APIs). | 91 // id (instead of invoking platform APIs). |
| 58 NetworkQualityEstimator::NetworkID GetCurrentNetworkID() const override { | 92 NetworkQualityEstimator::NetworkID GetCurrentNetworkID() const override { |
| 59 return NetworkQualityEstimator::NetworkID(current_network_type_, | 93 return NetworkQualityEstimator::NetworkID(current_network_type_, |
| 60 current_network_id_); | 94 current_network_id_); |
| 61 } | 95 } |
| 62 | 96 |
| 63 net::NetworkChangeNotifier::ConnectionType current_network_type_; | 97 net::NetworkChangeNotifier::ConnectionType current_network_type_; |
| 64 std::string current_network_id_; | 98 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); |
| 65 }; | 104 }; |
| 66 | 105 |
| 67 } // namespace | 106 } // namespace |
| 68 | 107 |
| 69 namespace net { | 108 namespace net { |
| 70 | 109 |
| 71 TEST(NetworkQualityEstimatorTest, TestKbpsRTTUpdates) { | 110 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 | |
| 77 base::HistogramTester histogram_tester; | 111 base::HistogramTester histogram_tester; |
| 78 // Enable requests to local host to be used for network quality estimation. | 112 // Enable requests to local host to be used for network quality estimation. |
| 79 std::map<std::string, std::string> variation_params; | 113 std::map<std::string, std::string> variation_params; |
| 80 TestNetworkQualityEstimator estimator(variation_params); | 114 TestNetworkQualityEstimator estimator(variation_params); |
| 81 | 115 |
| 82 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(), | 116 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(), |
| 83 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); | 117 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); |
| 84 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput, | 118 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput, |
| 85 estimator.GetDownlinkThroughputKbpsEstimateInternal( | 119 estimator.GetDownlinkThroughputKbpsEstimateInternal( |
| 86 base::TimeTicks(), 100)); | 120 base::TimeTicks(), 100)); |
| 87 | 121 |
| 88 TestDelegate test_delegate; | 122 TestDelegate test_delegate; |
| 89 TestURLRequestContext context(false); | 123 TestURLRequestContext context(true); |
| 124 context.set_network_quality_estimator(&estimator); |
| 125 context.Init(); |
| 90 | 126 |
| 91 scoped_ptr<URLRequest> request( | 127 scoped_ptr<URLRequest> request(context.CreateRequest( |
| 92 context.CreateRequest(embedded_test_server.GetURL("/echo.html"), | 128 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); |
| 93 DEFAULT_PRIORITY, &test_delegate)); | |
| 94 request->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME); | 129 request->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME); |
| 95 request->Start(); | 130 request->Start(); |
| 96 | |
| 97 base::RunLoop().Run(); | 131 base::RunLoop().Run(); |
| 98 | 132 |
| 99 // Both RTT and downstream throughput should be updated. | 133 // Both RTT and downstream throughput should be updated. |
| 100 estimator.NotifyHeadersReceived(*request); | |
| 101 estimator.NotifyRequestCompleted(*request); | |
| 102 EXPECT_NE(NetworkQualityEstimator::InvalidRTT(), | 134 EXPECT_NE(NetworkQualityEstimator::InvalidRTT(), |
| 103 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); | 135 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); |
| 104 EXPECT_NE(NetworkQualityEstimator::kInvalidThroughput, | 136 EXPECT_NE(NetworkQualityEstimator::kInvalidThroughput, |
| 105 estimator.GetDownlinkThroughputKbpsEstimateInternal( | 137 estimator.GetDownlinkThroughputKbpsEstimateInternal( |
| 106 base::TimeTicks(), 100)); | 138 base::TimeTicks(), 100)); |
| 107 | 139 |
| 108 base::TimeDelta rtt = NetworkQualityEstimator::InvalidRTT(); | 140 base::TimeDelta rtt = NetworkQualityEstimator::InvalidRTT(); |
| 109 int32_t kbps = NetworkQualityEstimator::kInvalidThroughput; | 141 int32_t kbps = NetworkQualityEstimator::kInvalidThroughput; |
| 110 EXPECT_TRUE(estimator.GetRTTEstimate(&rtt)); | 142 EXPECT_TRUE(estimator.GetRTTEstimate(&rtt)); |
| 111 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); | 143 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); |
| 112 EXPECT_NE(NetworkQualityEstimator::InvalidRTT(), rtt); | 144 EXPECT_NE(NetworkQualityEstimator::InvalidRTT(), rtt); |
| 113 EXPECT_NE(NetworkQualityEstimator::kInvalidThroughput, kbps); | 145 EXPECT_NE(NetworkQualityEstimator::kInvalidThroughput, kbps); |
| 114 | 146 |
| 115 EXPECT_NEAR( | 147 EXPECT_NEAR( |
| 116 rtt.InMilliseconds(), | 148 rtt.InMilliseconds(), |
| 117 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100).InMilliseconds(), | 149 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100).InMilliseconds(), |
| 118 1); | 150 1); |
| 119 | 151 |
| 120 // Check UMA histograms. | 152 // Check UMA histograms. |
| 121 histogram_tester.ExpectTotalCount("NQE.PeakKbps.Unknown", 0); | 153 histogram_tester.ExpectTotalCount("NQE.PeakKbps.Unknown", 0); |
| 122 histogram_tester.ExpectTotalCount("NQE.FastestRTT.Unknown", 0); | 154 histogram_tester.ExpectTotalCount("NQE.FastestRTT.Unknown", 0); |
| 123 | 155 |
| 124 histogram_tester.ExpectTotalCount("NQE.RatioEstimatedToActualRTT.Unknown", 0); | 156 histogram_tester.ExpectTotalCount("NQE.RatioEstimatedToActualRTT.Unknown", 0); |
| 125 | 157 |
| 126 estimator.NotifyHeadersReceived(*request); | 158 scoped_ptr<URLRequest> request2(context.CreateRequest( |
| 127 estimator.NotifyRequestCompleted(*request); | 159 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); |
| 160 request2->SetLoadFlags(request2->load_flags() | LOAD_MAIN_FRAME); |
| 161 request2->Start(); |
| 162 base::RunLoop().Run(); |
| 163 |
| 128 histogram_tester.ExpectTotalCount("NQE.RTTObservations.Unknown", 1); | 164 histogram_tester.ExpectTotalCount("NQE.RTTObservations.Unknown", 1); |
| 129 estimator.SimulateNetworkChangeTo( | 165 estimator.SimulateNetworkChangeTo( |
| 130 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test-1"); | 166 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test-1"); |
| 131 histogram_tester.ExpectTotalCount("NQE.PeakKbps.Unknown", 1); | 167 histogram_tester.ExpectTotalCount("NQE.PeakKbps.Unknown", 1); |
| 132 histogram_tester.ExpectTotalCount("NQE.FastestRTT.Unknown", 1); | 168 histogram_tester.ExpectTotalCount("NQE.FastestRTT.Unknown", 1); |
| 133 | 169 |
| 134 histogram_tester.ExpectTotalCount("NQE.RatioMedianRTT.WiFi", 0); | 170 histogram_tester.ExpectTotalCount("NQE.RatioMedianRTT.WiFi", 0); |
| 135 | 171 |
| 136 histogram_tester.ExpectTotalCount("NQE.RTT.Percentile0.Unknown", 1); | 172 histogram_tester.ExpectTotalCount("NQE.RTT.Percentile0.Unknown", 1); |
| 137 histogram_tester.ExpectTotalCount("NQE.RTT.Percentile10.Unknown", 1); | 173 histogram_tester.ExpectTotalCount("NQE.RTT.Percentile10.Unknown", 1); |
| (...skipping 21 matching lines...) Expand all Loading... |
| 159 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); | 195 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); |
| 160 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput, | 196 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput, |
| 161 estimator.GetDownlinkThroughputKbpsEstimateInternal( | 197 estimator.GetDownlinkThroughputKbpsEstimateInternal( |
| 162 base::TimeTicks(), 100)); | 198 base::TimeTicks(), 100)); |
| 163 | 199 |
| 164 EXPECT_FALSE(estimator.GetRTTEstimate(&rtt)); | 200 EXPECT_FALSE(estimator.GetRTTEstimate(&rtt)); |
| 165 EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); | 201 EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); |
| 166 } | 202 } |
| 167 | 203 |
| 168 TEST(NetworkQualityEstimatorTest, StoreObservations) { | 204 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 | |
| 174 std::map<std::string, std::string> variation_params; | 205 std::map<std::string, std::string> variation_params; |
| 175 TestNetworkQualityEstimator estimator(variation_params); | 206 TestNetworkQualityEstimator estimator(variation_params); |
| 207 |
| 176 TestDelegate test_delegate; | 208 TestDelegate test_delegate; |
| 177 TestURLRequestContext context(false); | 209 TestURLRequestContext context(true); |
| 210 context.set_network_quality_estimator(&estimator); |
| 211 context.Init(); |
| 178 | 212 |
| 179 // Push 10 more observations than the maximum buffer size. | 213 // Push 10 more observations than the maximum buffer size. |
| 180 for (size_t i = 0; i < estimator.kMaximumObservationsBufferSize + 10U; ++i) { | 214 for (size_t i = 0; i < estimator.kMaximumObservationsBufferSize + 10U; ++i) { |
| 181 scoped_ptr<URLRequest> request( | 215 scoped_ptr<URLRequest> request(context.CreateRequest( |
| 182 context.CreateRequest(embedded_test_server.GetURL("/echo.html"), | 216 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); |
| 183 DEFAULT_PRIORITY, &test_delegate)); | |
| 184 request->Start(); | 217 request->Start(); |
| 185 base::RunLoop().Run(); | 218 base::RunLoop().Run(); |
| 186 | |
| 187 estimator.NotifyHeadersReceived(*request); | |
| 188 estimator.NotifyRequestCompleted(*request); | |
| 189 } | 219 } |
| 190 | 220 |
| 191 EXPECT_EQ(static_cast<size_t>( | 221 EXPECT_EQ(static_cast<size_t>( |
| 192 NetworkQualityEstimator::kMaximumObservationsBufferSize), | 222 NetworkQualityEstimator::kMaximumObservationsBufferSize), |
| 193 estimator.downstream_throughput_kbps_observations_.Size()); | 223 estimator.downstream_throughput_kbps_observations_.Size()); |
| 194 EXPECT_EQ(static_cast<size_t>( | 224 EXPECT_EQ(static_cast<size_t>( |
| 195 NetworkQualityEstimator::kMaximumObservationsBufferSize), | 225 NetworkQualityEstimator::kMaximumObservationsBufferSize), |
| 196 estimator.rtt_msec_observations_.Size()); | 226 estimator.rtt_msec_observations_.Size()); |
| 197 | 227 |
| 198 // Verify that the stored observations are cleared on network change. | 228 // Verify that the stored observations are cleared on network change. |
| 199 estimator.SimulateNetworkChangeTo( | 229 estimator.SimulateNetworkChangeTo( |
| 200 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test-2"); | 230 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test-2"); |
| 201 EXPECT_EQ(0U, estimator.downstream_throughput_kbps_observations_.Size()); | 231 EXPECT_EQ(0U, estimator.downstream_throughput_kbps_observations_.Size()); |
| 202 EXPECT_EQ(0U, estimator.rtt_msec_observations_.Size()); | 232 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)); | |
| 207 } | 233 } |
| 208 | 234 |
| 209 // Verifies that the percentiles are correctly computed. All observations have | 235 // Verifies that the percentiles are correctly computed. All observations have |
| 210 // the same timestamp. Kbps percentiles must be in decreasing order. RTT | 236 // the same timestamp. Kbps percentiles must be in decreasing order. RTT |
| 211 // percentiles must be in increasing order. | 237 // percentiles must be in increasing order. |
| 212 TEST(NetworkQualityEstimatorTest, PercentileSameTimestamps) { | 238 TEST(NetworkQualityEstimatorTest, PercentileSameTimestamps) { |
| 213 std::map<std::string, std::string> variation_params; | 239 std::map<std::string, std::string> variation_params; |
| 214 TestNetworkQualityEstimator estimator(variation_params); | 240 TestNetworkQualityEstimator estimator(variation_params); |
| 215 base::TimeTicks now = base::TimeTicks::Now(); | 241 base::TimeTicks now = base::TimeTicks::Now(); |
| 216 | 242 |
| (...skipping 92 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 309 base::TimeTicks::Now() + base::TimeDelta::FromMinutes(10), 50)); | 335 base::TimeTicks::Now() + base::TimeDelta::FromMinutes(10), 50)); |
| 310 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput, | 336 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput, |
| 311 estimator.GetDownlinkThroughputKbpsEstimateInternal( | 337 estimator.GetDownlinkThroughputKbpsEstimateInternal( |
| 312 base::TimeTicks::Now() + base::TimeDelta::FromMinutes(10), 50)); | 338 base::TimeTicks::Now() + base::TimeDelta::FromMinutes(10), 50)); |
| 313 } | 339 } |
| 314 | 340 |
| 315 // This test notifies NetworkQualityEstimator of received data. Next, | 341 // This test notifies NetworkQualityEstimator of received data. Next, |
| 316 // throughput and RTT percentiles are checked for correctness by doing simple | 342 // throughput and RTT percentiles are checked for correctness by doing simple |
| 317 // verifications. | 343 // verifications. |
| 318 TEST(NetworkQualityEstimatorTest, ComputedPercentiles) { | 344 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 | |
| 324 std::map<std::string, std::string> variation_params; | 345 std::map<std::string, std::string> variation_params; |
| 325 TestNetworkQualityEstimator estimator(variation_params); | 346 TestNetworkQualityEstimator estimator(variation_params); |
| 326 | 347 |
| 327 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(), | 348 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(), |
| 328 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); | 349 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); |
| 329 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput, | 350 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput, |
| 330 estimator.GetDownlinkThroughputKbpsEstimateInternal( | 351 estimator.GetDownlinkThroughputKbpsEstimateInternal( |
| 331 base::TimeTicks(), 100)); | 352 base::TimeTicks(), 100)); |
| 332 | 353 |
| 333 TestDelegate test_delegate; | 354 TestDelegate test_delegate; |
| 334 TestURLRequestContext context(false); | 355 TestURLRequestContext context(true); |
| 356 context.set_network_quality_estimator(&estimator); |
| 357 context.Init(); |
| 335 | 358 |
| 336 // Number of observations are more than the maximum buffer size. | 359 // Number of observations are more than the maximum buffer size. |
| 337 for (size_t i = 0; i < estimator.kMaximumObservationsBufferSize + 100U; ++i) { | 360 for (size_t i = 0; i < estimator.kMaximumObservationsBufferSize + 100U; ++i) { |
| 338 scoped_ptr<URLRequest> request( | 361 scoped_ptr<URLRequest> request(context.CreateRequest( |
| 339 context.CreateRequest(embedded_test_server.GetURL("/echo.html"), | 362 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); |
| 340 DEFAULT_PRIORITY, &test_delegate)); | |
| 341 request->Start(); | 363 request->Start(); |
| 342 base::RunLoop().Run(); | 364 base::RunLoop().Run(); |
| 343 | |
| 344 // Use different number of bytes to create variation. | |
| 345 estimator.NotifyHeadersReceived(*request); | |
| 346 estimator.NotifyRequestCompleted(*request); | |
| 347 } | 365 } |
| 348 | 366 |
| 349 // Verify the percentiles through simple tests. | 367 // Verify the percentiles through simple tests. |
| 350 for (int i = 0; i <= 100; ++i) { | 368 for (int i = 0; i <= 100; ++i) { |
| 351 EXPECT_GT(estimator.GetDownlinkThroughputKbpsEstimateInternal( | 369 EXPECT_GT(estimator.GetDownlinkThroughputKbpsEstimateInternal( |
| 352 base::TimeTicks(), i), | 370 base::TimeTicks(), i), |
| 353 0); | 371 0); |
| 354 EXPECT_LT(estimator.GetRTTEstimateInternal(base::TimeTicks(), i), | 372 EXPECT_LT(estimator.GetRTTEstimateInternal(base::TimeTicks(), i), |
| 355 base::TimeDelta::Max()); | 373 base::TimeDelta::Max()); |
| 356 | 374 |
| (...skipping 290 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 647 EXPECT_EQ(100, rtt.InMilliseconds()); | 665 EXPECT_EQ(100, rtt.InMilliseconds()); |
| 648 | 666 |
| 649 int32_t downstream_throughput_kbps; | 667 int32_t downstream_throughput_kbps; |
| 650 EXPECT_FALSE(estimator.GetRecentMedianDownlinkThroughputKbps( | 668 EXPECT_FALSE(estimator.GetRecentMedianDownlinkThroughputKbps( |
| 651 now + base::TimeDelta::FromSeconds(10), &downstream_throughput_kbps)); | 669 now + base::TimeDelta::FromSeconds(10), &downstream_throughput_kbps)); |
| 652 EXPECT_TRUE(estimator.GetRecentMedianDownlinkThroughputKbps( | 670 EXPECT_TRUE(estimator.GetRecentMedianDownlinkThroughputKbps( |
| 653 now, &downstream_throughput_kbps)); | 671 now, &downstream_throughput_kbps)); |
| 654 EXPECT_EQ(100, downstream_throughput_kbps); | 672 EXPECT_EQ(100, downstream_throughput_kbps); |
| 655 } | 673 } |
| 656 | 674 |
| 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 |
| 657 } // namespace net | 937 } // namespace net |
| OLD | NEW |