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 |