Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(47)

Side by Side Diff: net/base/network_quality_estimator_unittest.cc

Issue 1898603002: Move Network Quality Estimator files to //net/nqe (Closed) Base URL: https://chromium.googlesource.com/chromium/src.git@master
Patch Set: Created 4 years, 8 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch
OLDNEW
(Empty)
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
3 // found in the LICENSE file.
4
5 #include "net/base/network_quality_estimator.h"
6
7 #include <stddef.h>
8 #include <stdint.h>
9
10 #include <limits>
11 #include <map>
12 #include <string>
13 #include <utility>
14 #include <vector>
15
16 #include "base/files/file_path.h"
17 #include "base/logging.h"
18 #include "base/macros.h"
19 #include "base/memory/scoped_ptr.h"
20 #include "base/metrics/histogram_samples.h"
21 #include "base/run_loop.h"
22 #include "base/strings/string_number_conversions.h"
23 #include "base/test/histogram_tester.h"
24 #include "base/time/time.h"
25 #include "build/build_config.h"
26 #include "net/base/external_estimate_provider.h"
27 #include "net/base/load_flags.h"
28 #include "net/base/network_change_notifier.h"
29 #include "net/base/socket_performance_watcher.h"
30 #include "net/base/socket_performance_watcher_factory.h"
31 #include "net/http/http_status_code.h"
32 #include "net/test/embedded_test_server/embedded_test_server.h"
33 #include "net/test/embedded_test_server/http_request.h"
34 #include "net/test/embedded_test_server/http_response.h"
35 #include "net/url_request/url_request.h"
36 #include "net/url_request/url_request_test_util.h"
37 #include "testing/gtest/include/gtest/gtest.h"
38 #include "url/gurl.h"
39
40 namespace {
41
42 // Helps in setting the current network type and id.
43 class TestNetworkQualityEstimator : public net::NetworkQualityEstimator {
44 public:
45 TestNetworkQualityEstimator(
46 const std::map<std::string, std::string>& variation_params,
47 scoped_ptr<net::ExternalEstimateProvider> external_estimate_provider)
48 : NetworkQualityEstimator(std::move(external_estimate_provider),
49 variation_params,
50 true,
51 true) {
52 // Set up embedded test server.
53 embedded_test_server_.ServeFilesFromDirectory(
54 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest")));
55 EXPECT_TRUE(embedded_test_server_.Start());
56 embedded_test_server_.RegisterRequestHandler(base::Bind(
57 &TestNetworkQualityEstimator::HandleRequest, base::Unretained(this)));
58 }
59
60 explicit TestNetworkQualityEstimator(
61 const std::map<std::string, std::string>& variation_params)
62 : TestNetworkQualityEstimator(
63 variation_params,
64 scoped_ptr<net::ExternalEstimateProvider>()) {}
65
66 ~TestNetworkQualityEstimator() override {}
67
68 // Overrides the current network type and id.
69 // Notifies network quality estimator of change in connection.
70 void SimulateNetworkChangeTo(net::NetworkChangeNotifier::ConnectionType type,
71 std::string network_id) {
72 current_network_type_ = type;
73 current_network_id_ = network_id;
74 OnConnectionTypeChanged(type);
75 }
76
77 // Called by embedded server when a HTTP request is received.
78 scoped_ptr<net::test_server::HttpResponse> HandleRequest(
79 const net::test_server::HttpRequest& request) {
80 scoped_ptr<net::test_server::BasicHttpResponse> http_response(
81 new net::test_server::BasicHttpResponse());
82 http_response->set_code(net::HTTP_OK);
83 http_response->set_content("hello");
84 http_response->set_content_type("text/plain");
85 return std::move(http_response);
86 }
87
88 // Returns a GURL hosted at embedded test server.
89 const GURL GetEchoURL() const {
90 return embedded_test_server_.GetURL("/echo.html");
91 }
92
93 using NetworkQualityEstimator::ReadCachedNetworkQualityEstimate;
94 using NetworkQualityEstimator::OnConnectionTypeChanged;
95
96 private:
97 // NetworkQualityEstimator implementation that returns the overridden network
98 // id (instead of invoking platform APIs).
99 NetworkQualityEstimator::NetworkID GetCurrentNetworkID() const override {
100 return NetworkQualityEstimator::NetworkID(current_network_type_,
101 current_network_id_);
102 }
103
104 net::NetworkChangeNotifier::ConnectionType current_network_type_;
105 std::string current_network_id_;
106
107 // Embedded server used for testing.
108 net::EmbeddedTestServer embedded_test_server_;
109
110 DISALLOW_COPY_AND_ASSIGN(TestNetworkQualityEstimator);
111 };
112
113 class TestRTTObserver : public net::NetworkQualityEstimator::RTTObserver {
114 public:
115 struct Observation {
116 Observation(int32_t ms,
117 const base::TimeTicks& ts,
118 net::NetworkQualityEstimator::ObservationSource src)
119 : rtt_ms(ms), timestamp(ts), source(src) {}
120 int32_t rtt_ms;
121 base::TimeTicks timestamp;
122 net::NetworkQualityEstimator::ObservationSource source;
123 };
124
125 std::vector<Observation>& observations() { return observations_; }
126
127 // RttObserver implementation:
128 void OnRTTObservation(
129 int32_t rtt_ms,
130 const base::TimeTicks& timestamp,
131 net::NetworkQualityEstimator::ObservationSource source) override {
132 observations_.push_back(Observation(rtt_ms, timestamp, source));
133 }
134
135 private:
136 std::vector<Observation> observations_;
137 };
138
139 class TestThroughputObserver
140 : public net::NetworkQualityEstimator::ThroughputObserver {
141 public:
142 struct Observation {
143 Observation(int32_t kbps,
144 const base::TimeTicks& ts,
145 net::NetworkQualityEstimator::ObservationSource src)
146 : throughput_kbps(kbps), timestamp(ts), source(src) {}
147 int32_t throughput_kbps;
148 base::TimeTicks timestamp;
149 net::NetworkQualityEstimator::ObservationSource source;
150 };
151
152 std::vector<Observation>& observations() { return observations_; }
153
154 // ThroughputObserver implementation:
155 void OnThroughputObservation(
156 int32_t throughput_kbps,
157 const base::TimeTicks& timestamp,
158 net::NetworkQualityEstimator::ObservationSource source) override {
159 observations_.push_back(Observation(throughput_kbps, timestamp, source));
160 }
161
162 private:
163 std::vector<Observation> observations_;
164 };
165
166 } // namespace
167
168 namespace net {
169
170 TEST(NetworkQualityEstimatorTest, TestKbpsRTTUpdates) {
171 base::HistogramTester histogram_tester;
172 // Enable requests to local host to be used for network quality estimation.
173 std::map<std::string, std::string> variation_params;
174 TestNetworkQualityEstimator estimator(variation_params);
175
176 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(),
177 estimator.GetURLRequestRTTEstimateInternal(base::TimeTicks(), 100));
178 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput,
179 estimator.GetDownlinkThroughputKbpsEstimateInternal(
180 base::TimeTicks(), 100));
181
182 TestDelegate test_delegate;
183 TestURLRequestContext context(true);
184 context.set_network_quality_estimator(&estimator);
185 context.Init();
186
187 scoped_ptr<URLRequest> request(context.CreateRequest(
188 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate));
189 request->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME);
190 request->Start();
191 base::RunLoop().Run();
192
193 // Both RTT and downstream throughput should be updated.
194 EXPECT_NE(NetworkQualityEstimator::InvalidRTT(),
195 estimator.GetURLRequestRTTEstimateInternal(base::TimeTicks(), 100));
196 EXPECT_NE(NetworkQualityEstimator::kInvalidThroughput,
197 estimator.GetDownlinkThroughputKbpsEstimateInternal(
198 base::TimeTicks(), 100));
199
200 base::TimeDelta rtt = NetworkQualityEstimator::InvalidRTT();
201 int32_t kbps = NetworkQualityEstimator::kInvalidThroughput;
202 EXPECT_TRUE(estimator.GetURLRequestRTTEstimate(&rtt));
203 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
204 EXPECT_NE(NetworkQualityEstimator::InvalidRTT(), rtt);
205 EXPECT_NE(NetworkQualityEstimator::kInvalidThroughput, kbps);
206
207 EXPECT_NEAR(rtt.InMilliseconds(),
208 estimator.GetURLRequestRTTEstimateInternal(base::TimeTicks(), 100)
209 .InMilliseconds(),
210 1);
211
212 // Check UMA histograms.
213 histogram_tester.ExpectTotalCount("NQE.PeakKbps.Unknown", 0);
214 histogram_tester.ExpectTotalCount("NQE.FastestRTT.Unknown", 0);
215
216 histogram_tester.ExpectTotalCount("NQE.RatioEstimatedToActualRTT.Unknown", 0);
217
218 scoped_ptr<URLRequest> request2(context.CreateRequest(
219 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate));
220 request2->SetLoadFlags(request2->load_flags() | LOAD_MAIN_FRAME);
221 request2->Start();
222 base::RunLoop().Run();
223
224 histogram_tester.ExpectTotalCount("NQE.RTTObservations.Unknown", 1);
225 estimator.SimulateNetworkChangeTo(
226 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test-1");
227 histogram_tester.ExpectTotalCount("NQE.PeakKbps.Unknown", 1);
228 histogram_tester.ExpectTotalCount("NQE.FastestRTT.Unknown", 1);
229
230 histogram_tester.ExpectTotalCount("NQE.RatioMedianRTT.WiFi", 0);
231
232 histogram_tester.ExpectTotalCount("NQE.RTT.Percentile0.Unknown", 1);
233 histogram_tester.ExpectTotalCount("NQE.RTT.Percentile10.Unknown", 1);
234 histogram_tester.ExpectTotalCount("NQE.RTT.Percentile50.Unknown", 1);
235 histogram_tester.ExpectTotalCount("NQE.RTT.Percentile90.Unknown", 1);
236 histogram_tester.ExpectTotalCount("NQE.RTT.Percentile100.Unknown", 1);
237
238 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(),
239 estimator.GetURLRequestRTTEstimateInternal(base::TimeTicks(), 100));
240 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput,
241 estimator.GetDownlinkThroughputKbpsEstimateInternal(
242 base::TimeTicks(), 100));
243
244 EXPECT_FALSE(estimator.GetURLRequestRTTEstimate(&rtt));
245 EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
246 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(), rtt);
247 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput, kbps);
248
249 estimator.SimulateNetworkChangeTo(
250 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, std::string());
251 histogram_tester.ExpectTotalCount("NQE.PeakKbps.Unknown", 1);
252 histogram_tester.ExpectTotalCount("NQE.FastestRTT.Unknown", 1);
253
254 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(),
255 estimator.GetURLRequestRTTEstimateInternal(base::TimeTicks(), 100));
256 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput,
257 estimator.GetDownlinkThroughputKbpsEstimateInternal(
258 base::TimeTicks(), 100));
259
260 EXPECT_FALSE(estimator.GetURLRequestRTTEstimate(&rtt));
261 EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
262 }
263
264 TEST(NetworkQualityEstimatorTest, StoreObservations) {
265 std::map<std::string, std::string> variation_params;
266 TestNetworkQualityEstimator estimator(variation_params);
267
268 TestDelegate test_delegate;
269 TestURLRequestContext context(true);
270 context.set_network_quality_estimator(&estimator);
271 context.Init();
272
273 // Push 10 more observations than the maximum buffer size.
274 for (size_t i = 0; i < estimator.kMaximumObservationsBufferSize + 10U; ++i) {
275 scoped_ptr<URLRequest> request(context.CreateRequest(
276 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate));
277 request->Start();
278 base::RunLoop().Run();
279 }
280
281 EXPECT_EQ(static_cast<size_t>(
282 NetworkQualityEstimator::kMaximumObservationsBufferSize),
283 estimator.downstream_throughput_kbps_observations_.Size());
284 EXPECT_EQ(static_cast<size_t>(
285 NetworkQualityEstimator::kMaximumObservationsBufferSize),
286 estimator.rtt_observations_.Size());
287
288 // Verify that the stored observations are cleared on network change.
289 estimator.SimulateNetworkChangeTo(
290 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test-2");
291 EXPECT_EQ(0U, estimator.downstream_throughput_kbps_observations_.Size());
292 EXPECT_EQ(0U, estimator.rtt_observations_.Size());
293 }
294
295 // Verifies that the percentiles are correctly computed. All observations have
296 // the same timestamp. Kbps percentiles must be in decreasing order. RTT
297 // percentiles must be in increasing order.
298 TEST(NetworkQualityEstimatorTest, PercentileSameTimestamps) {
299 std::map<std::string, std::string> variation_params;
300 TestNetworkQualityEstimator estimator(variation_params);
301 base::TimeTicks now = base::TimeTicks::Now();
302
303 // Network quality should be unavailable when no observations are available.
304 base::TimeDelta rtt;
305 EXPECT_FALSE(estimator.GetURLRequestRTTEstimate(&rtt));
306 int32_t kbps;
307 EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
308
309 // Insert samples from {1,2,3,..., 100}. First insert odd samples, then even
310 // samples. This helps in verifying that the order of samples does not matter.
311 for (int i = 1; i <= 99; i += 2) {
312 estimator.downstream_throughput_kbps_observations_.AddObservation(
313 NetworkQualityEstimator::ThroughputObservation(
314 i, now, NetworkQualityEstimator::URL_REQUEST));
315 estimator.rtt_observations_.AddObservation(
316 NetworkQualityEstimator::RttObservation(
317 base::TimeDelta::FromMilliseconds(i), now,
318 NetworkQualityEstimator::URL_REQUEST));
319 EXPECT_TRUE(estimator.GetURLRequestRTTEstimate(&rtt));
320 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
321 }
322
323 for (int i = 1; i <= 99; i += 2) {
324 // Insert TCP observation which should not be taken into account when
325 // computing median RTT at HTTP layer.
326 estimator.rtt_observations_.AddObservation(
327 NetworkQualityEstimator::RttObservation(
328 base::TimeDelta::FromMilliseconds(10000), now,
329 NetworkQualityEstimator::TCP));
330
331 // Insert QUIC observation which should not be taken into account when
332 // computing median RTT at HTTP layer.
333 estimator.rtt_observations_.AddObservation(
334 NetworkQualityEstimator::RttObservation(
335 base::TimeDelta::FromMilliseconds(10000), now,
336 NetworkQualityEstimator::QUIC));
337 }
338
339 for (int i = 2; i <= 100; i += 2) {
340 estimator.downstream_throughput_kbps_observations_.AddObservation(
341 NetworkQualityEstimator::ThroughputObservation(
342 i, now, NetworkQualityEstimator::URL_REQUEST));
343 estimator.rtt_observations_.AddObservation(
344 NetworkQualityEstimator::RttObservation(
345 base::TimeDelta::FromMilliseconds(i), now,
346 NetworkQualityEstimator::URL_REQUEST));
347 EXPECT_TRUE(estimator.GetURLRequestRTTEstimate(&rtt));
348 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
349 }
350
351 for (int i = 0; i <= 100; ++i) {
352 // Checks if the difference between the two integers is less than 1. This is
353 // required because computed percentiles may be slightly different from
354 // what is expected due to floating point computation errors and integer
355 // rounding off errors.
356 EXPECT_NEAR(estimator.GetDownlinkThroughputKbpsEstimateInternal(
357 base::TimeTicks(), i),
358 100 - i, 1);
359 EXPECT_NEAR(estimator.GetURLRequestRTTEstimateInternal(base::TimeTicks(), i)
360 .InMilliseconds(),
361 i, 1);
362 }
363
364 EXPECT_TRUE(estimator.GetURLRequestRTTEstimate(&rtt));
365 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
366 // |network_quality| should be equal to the 50 percentile value.
367 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimateInternal(
368 base::TimeTicks(), 50) > 0);
369 EXPECT_TRUE(
370 estimator.GetURLRequestRTTEstimateInternal(base::TimeTicks(), 50) !=
371 NetworkQualityEstimator::InvalidRTT());
372 }
373
374 // Verifies that the percentiles are correctly computed. Observations have
375 // different timestamps with half the observations being very old and the rest
376 // of them being very recent. Percentiles should factor in recent observations
377 // much more heavily than older samples. Kbps percentiles must be in decreasing
378 // order. RTT percentiles must be in increasing order.
379 TEST(NetworkQualityEstimatorTest, PercentileDifferentTimestamps) {
380 std::map<std::string, std::string> variation_params;
381 TestNetworkQualityEstimator estimator(variation_params);
382 base::TimeTicks now = base::TimeTicks::Now();
383 base::TimeTicks very_old = now - base::TimeDelta::FromDays(365);
384
385 // First 50 samples have very old timestamp.
386 for (int i = 1; i <= 50; ++i) {
387 estimator.downstream_throughput_kbps_observations_.AddObservation(
388 NetworkQualityEstimator::ThroughputObservation(
389 i, very_old, NetworkQualityEstimator::URL_REQUEST));
390 estimator.rtt_observations_.AddObservation(
391 NetworkQualityEstimator::RttObservation(
392 base::TimeDelta::FromMilliseconds(i), very_old,
393 NetworkQualityEstimator::URL_REQUEST));
394 }
395
396 // Next 50 (i.e., from 51 to 100) have recent timestamp.
397 for (int i = 51; i <= 100; ++i) {
398 estimator.downstream_throughput_kbps_observations_.AddObservation(
399 NetworkQualityEstimator::ThroughputObservation(
400 i, now, NetworkQualityEstimator::URL_REQUEST));
401 estimator.rtt_observations_.AddObservation(
402 NetworkQualityEstimator::RttObservation(
403 base::TimeDelta::FromMilliseconds(i), now,
404 NetworkQualityEstimator::URL_REQUEST));
405 }
406
407 // Older samples have very little weight. So, all percentiles are >= 51
408 // (lowest value among recent observations).
409 for (int i = 1; i < 100; ++i) {
410 // Checks if the difference between the two integers is less than 1. This is
411 // required because computed percentiles may be slightly different from
412 // what is expected due to floating point computation errors and integer
413 // rounding off errors.
414 EXPECT_NEAR(estimator.GetDownlinkThroughputKbpsEstimateInternal(
415 base::TimeTicks(), i),
416 51 + 0.49 * (100 - i), 1);
417 EXPECT_NEAR(estimator.GetURLRequestRTTEstimateInternal(base::TimeTicks(), i)
418 .InMilliseconds(),
419 51 + 0.49 * i, 1);
420 }
421
422 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(),
423 estimator.GetURLRequestRTTEstimateInternal(
424 base::TimeTicks::Now() + base::TimeDelta::FromMinutes(10), 50));
425 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput,
426 estimator.GetDownlinkThroughputKbpsEstimateInternal(
427 base::TimeTicks::Now() + base::TimeDelta::FromMinutes(10), 50));
428 }
429
430 // This test notifies NetworkQualityEstimator of received data. Next,
431 // throughput and RTT percentiles are checked for correctness by doing simple
432 // verifications.
433 TEST(NetworkQualityEstimatorTest, ComputedPercentiles) {
434 std::map<std::string, std::string> variation_params;
435 TestNetworkQualityEstimator estimator(variation_params);
436
437 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(),
438 estimator.GetURLRequestRTTEstimateInternal(base::TimeTicks(), 100));
439 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput,
440 estimator.GetDownlinkThroughputKbpsEstimateInternal(
441 base::TimeTicks(), 100));
442
443 TestDelegate test_delegate;
444 TestURLRequestContext context(true);
445 context.set_network_quality_estimator(&estimator);
446 context.Init();
447
448 // Number of observations are more than the maximum buffer size.
449 for (size_t i = 0; i < estimator.kMaximumObservationsBufferSize + 100U; ++i) {
450 scoped_ptr<URLRequest> request(context.CreateRequest(
451 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate));
452 request->Start();
453 base::RunLoop().Run();
454 }
455
456 // Verify the percentiles through simple tests.
457 for (int i = 0; i <= 100; ++i) {
458 EXPECT_GT(estimator.GetDownlinkThroughputKbpsEstimateInternal(
459 base::TimeTicks(), i),
460 0);
461 EXPECT_LT(estimator.GetURLRequestRTTEstimateInternal(base::TimeTicks(), i),
462 base::TimeDelta::Max());
463
464 if (i != 0) {
465 // Throughput percentiles are in decreasing order.
466 EXPECT_LE(estimator.GetDownlinkThroughputKbpsEstimateInternal(
467 base::TimeTicks(), i),
468 estimator.GetDownlinkThroughputKbpsEstimateInternal(
469 base::TimeTicks(), i - 1));
470
471 // RTT percentiles are in increasing order.
472 EXPECT_GE(
473 estimator.GetURLRequestRTTEstimateInternal(base::TimeTicks(), i),
474 estimator.GetURLRequestRTTEstimateInternal(base::TimeTicks(), i - 1));
475 }
476 }
477 }
478
479 TEST(NetworkQualityEstimatorTest, ObtainOperatingParams) {
480 std::map<std::string, std::string> variation_params;
481 variation_params["Unknown.DefaultMedianKbps"] = "100";
482 variation_params["WiFi.DefaultMedianKbps"] = "200";
483 variation_params["2G.DefaultMedianKbps"] = "300";
484
485 variation_params["Unknown.DefaultMedianRTTMsec"] = "1000";
486 variation_params["WiFi.DefaultMedianRTTMsec"] = "2000";
487 // Negative variation value should not be used.
488 variation_params["2G.DefaultMedianRTTMsec"] = "-5";
489
490 TestNetworkQualityEstimator estimator(variation_params);
491 EXPECT_EQ(1U, estimator.downstream_throughput_kbps_observations_.Size());
492 EXPECT_EQ(1U, estimator.rtt_observations_.Size());
493
494 base::TimeDelta rtt;
495 EXPECT_TRUE(estimator.GetURLRequestRTTEstimate(&rtt));
496 int32_t kbps;
497 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
498
499 EXPECT_EQ(100, kbps);
500 EXPECT_EQ(base::TimeDelta::FromMilliseconds(1000), rtt);
501 auto throughput_iterator =
502 estimator.downstream_throughput_kbps_observations_.observations_.begin();
503 EXPECT_EQ(100, (*throughput_iterator).value);
504 auto rtt_iterator = estimator.rtt_observations_.observations_.begin();
505 EXPECT_EQ(base::TimeDelta::FromMilliseconds(1000), (*rtt_iterator).value);
506
507 // Simulate network change to Wi-Fi.
508 estimator.SimulateNetworkChangeTo(
509 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test-1");
510 EXPECT_EQ(1U, estimator.downstream_throughput_kbps_observations_.Size());
511 EXPECT_EQ(1U, estimator.rtt_observations_.Size());
512
513 EXPECT_TRUE(estimator.GetURLRequestRTTEstimate(&rtt));
514 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
515 EXPECT_EQ(200, kbps);
516 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2000), rtt);
517
518 throughput_iterator =
519 estimator.downstream_throughput_kbps_observations_.observations_.begin();
520 EXPECT_EQ(200, (*throughput_iterator).value);
521 rtt_iterator = estimator.rtt_observations_.observations_.begin();
522 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2000), (*rtt_iterator).value);
523
524 // Peak network quality should not be affected by the network quality
525 // estimator field trial.
526 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(),
527 estimator.peak_network_quality_.rtt());
528 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput,
529 estimator.peak_network_quality_.downstream_throughput_kbps());
530
531 // Simulate network change to 2G. Only the Kbps default estimate should be
532 // available.
533 estimator.SimulateNetworkChangeTo(
534 NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test-2");
535 EXPECT_EQ(1U, estimator.downstream_throughput_kbps_observations_.Size());
536 EXPECT_EQ(0U, estimator.rtt_observations_.Size());
537
538 EXPECT_FALSE(estimator.GetURLRequestRTTEstimate(&rtt));
539 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
540
541 throughput_iterator =
542 estimator.downstream_throughput_kbps_observations_.observations_.begin();
543 EXPECT_EQ(300, (*throughput_iterator).value);
544
545 // Simulate network change to 3G. Default estimates should be unavailable.
546 estimator.SimulateNetworkChangeTo(
547 NetworkChangeNotifier::ConnectionType::CONNECTION_3G, "test-3");
548
549 EXPECT_FALSE(estimator.GetURLRequestRTTEstimate(&rtt));
550 EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
551 EXPECT_EQ(0U, estimator.downstream_throughput_kbps_observations_.Size());
552 EXPECT_EQ(0U, estimator.rtt_observations_.Size());
553 }
554
555 TEST(NetworkQualityEstimatorTest, HalfLifeParam) {
556 // Verifies if |weight_multiplier_per_second_| is set to correct value for
557 // various values of half life parameter.
558 std::map<std::string, std::string> variation_params;
559 {
560 // Half life parameter is not set. Default value of
561 // |weight_multiplier_per_second_| should be used.
562 TestNetworkQualityEstimator estimator(variation_params);
563 EXPECT_NEAR(0.988, estimator.downstream_throughput_kbps_observations_
564 .weight_multiplier_per_second_,
565 0.001);
566 }
567
568 variation_params["HalfLifeSeconds"] = "-100";
569 {
570 // Half life parameter is set to a negative value. Default value of
571 // |weight_multiplier_per_second_| should be used.
572 TestNetworkQualityEstimator estimator(variation_params);
573 EXPECT_NEAR(0.988, estimator.downstream_throughput_kbps_observations_
574 .weight_multiplier_per_second_,
575 0.001);
576 }
577
578 variation_params["HalfLifeSeconds"] = "0";
579 {
580 // Half life parameter is set to zero. Default value of
581 // |weight_multiplier_per_second_| should be used.
582 TestNetworkQualityEstimator estimator(variation_params);
583 EXPECT_NEAR(0.988, estimator.downstream_throughput_kbps_observations_
584 .weight_multiplier_per_second_,
585 0.001);
586 }
587
588 variation_params["HalfLifeSeconds"] = "10";
589 {
590 // Half life parameter is set to a valid value.
591 TestNetworkQualityEstimator estimator(variation_params);
592 EXPECT_NEAR(0.933, estimator.downstream_throughput_kbps_observations_
593 .weight_multiplier_per_second_,
594 0.001);
595 }
596 }
597
598 // Test if the network estimates are cached when network change notification
599 // is invoked.
600 TEST(NetworkQualityEstimatorTest, TestCaching) {
601 std::map<std::string, std::string> variation_params;
602 TestNetworkQualityEstimator estimator(variation_params);
603 size_t expected_cache_size = 0;
604 EXPECT_EQ(expected_cache_size, estimator.cached_network_qualities_.size());
605
606 // Cache entry will not be added for (NONE, "").
607 estimator.downstream_throughput_kbps_observations_.AddObservation(
608 NetworkQualityEstimator::ThroughputObservation(
609 1, base::TimeTicks::Now(), NetworkQualityEstimator::URL_REQUEST));
610 estimator.rtt_observations_.AddObservation(
611 NetworkQualityEstimator::RttObservation(
612 base::TimeDelta::FromMilliseconds(1000), base::TimeTicks::Now(),
613 NetworkQualityEstimator::URL_REQUEST));
614 estimator.SimulateNetworkChangeTo(
615 NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test-1");
616 EXPECT_EQ(expected_cache_size, estimator.cached_network_qualities_.size());
617
618 // Entry will be added for (2G, "test1").
619 // Also, set the network quality for (2G, "test1") so that it is stored in
620 // the cache.
621 estimator.downstream_throughput_kbps_observations_.AddObservation(
622 NetworkQualityEstimator::ThroughputObservation(
623 1, base::TimeTicks::Now(), NetworkQualityEstimator::URL_REQUEST));
624 estimator.rtt_observations_.AddObservation(
625 NetworkQualityEstimator::RttObservation(
626 base::TimeDelta::FromMilliseconds(1000), base::TimeTicks::Now(),
627 NetworkQualityEstimator::URL_REQUEST));
628
629 estimator.SimulateNetworkChangeTo(
630 NetworkChangeNotifier::ConnectionType::CONNECTION_3G, "test-1");
631 ++expected_cache_size;
632 EXPECT_EQ(expected_cache_size, estimator.cached_network_qualities_.size());
633
634 // Entry will be added for (3G, "test1").
635 // Also, set the network quality for (3G, "test1") so that it is stored in
636 // the cache.
637 estimator.downstream_throughput_kbps_observations_.AddObservation(
638 NetworkQualityEstimator::ThroughputObservation(
639 2, base::TimeTicks::Now(), NetworkQualityEstimator::URL_REQUEST));
640 estimator.rtt_observations_.AddObservation(
641 NetworkQualityEstimator::RttObservation(
642 base::TimeDelta::FromMilliseconds(500), base::TimeTicks::Now(),
643 NetworkQualityEstimator::URL_REQUEST));
644 estimator.SimulateNetworkChangeTo(
645 NetworkChangeNotifier::ConnectionType::CONNECTION_3G, "test-2");
646 ++expected_cache_size;
647 EXPECT_EQ(expected_cache_size, estimator.cached_network_qualities_.size());
648
649 // Entry will not be added for (3G, "test2").
650 estimator.SimulateNetworkChangeTo(
651 NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test-1");
652 EXPECT_EQ(expected_cache_size, estimator.cached_network_qualities_.size());
653
654 // Read the network quality for (2G, "test-1").
655 EXPECT_TRUE(estimator.ReadCachedNetworkQualityEstimate());
656
657 base::TimeDelta rtt;
658 int32_t kbps;
659 EXPECT_TRUE(estimator.GetURLRequestRTTEstimate(&rtt));
660 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
661 EXPECT_EQ(1, kbps);
662 EXPECT_EQ(base::TimeDelta::FromMilliseconds(1000), rtt);
663 // No new entry should be added for (2G, "test-1") since it already exists
664 // in the cache.
665 estimator.SimulateNetworkChangeTo(
666 NetworkChangeNotifier::ConnectionType::CONNECTION_3G, "test-1");
667 EXPECT_EQ(expected_cache_size, estimator.cached_network_qualities_.size());
668
669 // Read the network quality for (3G, "test-1").
670 EXPECT_TRUE(estimator.ReadCachedNetworkQualityEstimate());
671 EXPECT_TRUE(estimator.GetURLRequestRTTEstimate(&rtt));
672 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
673 EXPECT_EQ(2, kbps);
674 EXPECT_EQ(base::TimeDelta::FromMilliseconds(500), rtt);
675 // No new entry should be added for (3G, "test1") since it already exists
676 // in the cache.
677 estimator.SimulateNetworkChangeTo(
678 NetworkChangeNotifier::ConnectionType::CONNECTION_3G, "test-2");
679 EXPECT_EQ(expected_cache_size, estimator.cached_network_qualities_.size());
680
681 // Reading quality of (3G, "test-2") should return false.
682 EXPECT_FALSE(estimator.ReadCachedNetworkQualityEstimate());
683
684 // Reading quality of (2G, "test-3") should return false.
685 estimator.SimulateNetworkChangeTo(
686 NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test-3");
687 EXPECT_FALSE(estimator.ReadCachedNetworkQualityEstimate());
688 }
689
690 // Tests if the cache size remains bounded. Also, ensure that the cache is
691 // LRU.
692 TEST(NetworkQualityEstimatorTest, TestLRUCacheMaximumSize) {
693 std::map<std::string, std::string> variation_params;
694 TestNetworkQualityEstimator estimator(variation_params);
695 estimator.SimulateNetworkChangeTo(
696 net::NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI,
697 std::string());
698 EXPECT_EQ(0U, estimator.cached_network_qualities_.size());
699
700 // Add 100 more networks than the maximum size of the cache.
701 size_t network_count =
702 NetworkQualityEstimator::kMaximumNetworkQualityCacheSize + 100;
703
704 base::TimeTicks update_time_of_network_100;
705 for (size_t i = 0; i < network_count; ++i) {
706 estimator.downstream_throughput_kbps_observations_.AddObservation(
707 NetworkQualityEstimator::ThroughputObservation(
708 2, base::TimeTicks::Now(), NetworkQualityEstimator::URL_REQUEST));
709 estimator.rtt_observations_.AddObservation(
710 NetworkQualityEstimator::RttObservation(
711 base::TimeDelta::FromMilliseconds(500), base::TimeTicks::Now(),
712 NetworkQualityEstimator::URL_REQUEST));
713
714 if (i == 100)
715 update_time_of_network_100 = base::TimeTicks::Now();
716
717 estimator.SimulateNetworkChangeTo(
718 net::NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI,
719 base::SizeTToString(i));
720 if (i < NetworkQualityEstimator::kMaximumNetworkQualityCacheSize)
721 EXPECT_EQ(i, estimator.cached_network_qualities_.size());
722 EXPECT_LE(estimator.cached_network_qualities_.size(),
723 static_cast<size_t>(
724 NetworkQualityEstimator::kMaximumNetworkQualityCacheSize));
725 }
726 // One more call so that the last network is also written to cache.
727 estimator.downstream_throughput_kbps_observations_.AddObservation(
728 NetworkQualityEstimator::ThroughputObservation(
729 2, base::TimeTicks::Now(), NetworkQualityEstimator::URL_REQUEST));
730 estimator.rtt_observations_.AddObservation(
731 NetworkQualityEstimator::RttObservation(
732 base::TimeDelta::FromMilliseconds(500), base::TimeTicks::Now(),
733 NetworkQualityEstimator::URL_REQUEST));
734 estimator.SimulateNetworkChangeTo(
735 net::NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI,
736 base::SizeTToString(network_count - 1));
737 EXPECT_EQ(static_cast<size_t>(
738 NetworkQualityEstimator::kMaximumNetworkQualityCacheSize),
739 estimator.cached_network_qualities_.size());
740
741 // Test that the cache is LRU by examining its contents. Networks in cache
742 // must all be newer than the 100th network.
743 for (NetworkQualityEstimator::CachedNetworkQualities::iterator it =
744 estimator.cached_network_qualities_.begin();
745 it != estimator.cached_network_qualities_.end(); ++it) {
746 EXPECT_GE((it->second).last_update_time_, update_time_of_network_100);
747 }
748 }
749
750 TEST(NetworkQualityEstimatorTest, TestGetMedianRTTSince) {
751 std::map<std::string, std::string> variation_params;
752 TestNetworkQualityEstimator estimator(variation_params);
753 base::TimeTicks now = base::TimeTicks::Now();
754 base::TimeTicks old = now - base::TimeDelta::FromMilliseconds(1);
755 ASSERT_NE(old, now);
756
757 // First sample has very old timestamp.
758 estimator.downstream_throughput_kbps_observations_.AddObservation(
759 NetworkQualityEstimator::ThroughputObservation(
760 1, old, NetworkQualityEstimator::URL_REQUEST));
761 estimator.rtt_observations_.AddObservation(
762 NetworkQualityEstimator::RttObservation(
763 base::TimeDelta::FromMilliseconds(1), old,
764 NetworkQualityEstimator::URL_REQUEST));
765
766 estimator.downstream_throughput_kbps_observations_.AddObservation(
767 NetworkQualityEstimator::ThroughputObservation(
768 100, now, NetworkQualityEstimator::URL_REQUEST));
769 estimator.rtt_observations_.AddObservation(
770 NetworkQualityEstimator::RttObservation(
771 base::TimeDelta::FromMilliseconds(100), now,
772 NetworkQualityEstimator::URL_REQUEST));
773
774 base::TimeDelta rtt;
775 EXPECT_FALSE(estimator.GetRecentURLRequestRTTMedian(
776 now + base::TimeDelta::FromSeconds(10), &rtt));
777 EXPECT_TRUE(estimator.GetRecentURLRequestRTTMedian(now, &rtt));
778 EXPECT_EQ(100, rtt.InMilliseconds());
779
780 int32_t downstream_throughput_kbps;
781 EXPECT_FALSE(estimator.GetRecentMedianDownlinkThroughputKbps(
782 now + base::TimeDelta::FromSeconds(10), &downstream_throughput_kbps));
783 EXPECT_TRUE(estimator.GetRecentMedianDownlinkThroughputKbps(
784 now, &downstream_throughput_kbps));
785 EXPECT_EQ(100, downstream_throughput_kbps);
786 }
787
788 // An external estimate provider that does not have a valid RTT or throughput
789 // estimate.
790 class InvalidExternalEstimateProvider : public ExternalEstimateProvider {
791 public:
792 InvalidExternalEstimateProvider() : get_rtt_count_(0) {}
793 ~InvalidExternalEstimateProvider() override {}
794
795 // ExternalEstimateProvider implementation:
796 bool GetRTT(base::TimeDelta* rtt) const override {
797 DCHECK(rtt);
798 get_rtt_count_++;
799 return false;
800 }
801
802 // ExternalEstimateProvider implementation:
803 bool GetDownstreamThroughputKbps(
804 int32_t* downstream_throughput_kbps) const override {
805 DCHECK(downstream_throughput_kbps);
806 return false;
807 }
808
809 // ExternalEstimateProvider implementation:
810 bool GetUpstreamThroughputKbps(
811 int32_t* upstream_throughput_kbps) const override {
812 // NetworkQualityEstimator does not support upstream throughput.
813 ADD_FAILURE();
814 return false;
815 }
816
817 // ExternalEstimateProvider implementation:
818 bool GetTimeSinceLastUpdate(
819 base::TimeDelta* time_since_last_update) const override {
820 *time_since_last_update = base::TimeDelta::FromMilliseconds(1);
821 return true;
822 }
823
824 // ExternalEstimateProvider implementation:
825 void SetUpdatedEstimateDelegate(UpdatedEstimateDelegate* delegate) override {}
826
827 // ExternalEstimateProvider implementation:
828 void Update() const override {}
829
830 size_t get_rtt_count() const { return get_rtt_count_; }
831
832 private:
833 // Keeps track of number of times different functions were called.
834 mutable size_t get_rtt_count_;
835
836 DISALLOW_COPY_AND_ASSIGN(InvalidExternalEstimateProvider);
837 };
838
839 // Tests if the RTT value from external estimate provider is discarded if the
840 // external estimate provider is invalid.
841 TEST(NetworkQualityEstimatorTest, InvalidExternalEstimateProvider) {
842 InvalidExternalEstimateProvider* invalid_external_estimate_provider =
843 new InvalidExternalEstimateProvider();
844 scoped_ptr<ExternalEstimateProvider> external_estimate_provider(
845 invalid_external_estimate_provider);
846
847 TestNetworkQualityEstimator estimator(std::map<std::string, std::string>(),
848 std::move(external_estimate_provider));
849
850 base::TimeDelta rtt;
851 int32_t kbps;
852 EXPECT_EQ(1U, invalid_external_estimate_provider->get_rtt_count());
853 EXPECT_FALSE(estimator.GetURLRequestRTTEstimate(&rtt));
854 EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
855 }
856
857 class TestExternalEstimateProvider : public ExternalEstimateProvider {
858 public:
859 TestExternalEstimateProvider(base::TimeDelta rtt,
860 int32_t downstream_throughput_kbps)
861 : rtt_(rtt),
862 downstream_throughput_kbps_(downstream_throughput_kbps),
863 time_since_last_update_(base::TimeDelta::FromSeconds(1)),
864 get_time_since_last_update_count_(0),
865 get_rtt_count_(0),
866 get_downstream_throughput_kbps_count_(0),
867 update_count_(0) {}
868 ~TestExternalEstimateProvider() override {}
869
870 // ExternalEstimateProvider implementation:
871 bool GetRTT(base::TimeDelta* rtt) const override {
872 *rtt = rtt_;
873 get_rtt_count_++;
874 return true;
875 }
876
877 // ExternalEstimateProvider implementation:
878 bool GetDownstreamThroughputKbps(
879 int32_t* downstream_throughput_kbps) const override {
880 *downstream_throughput_kbps = downstream_throughput_kbps_;
881 get_downstream_throughput_kbps_count_++;
882 return true;
883 }
884
885 // ExternalEstimateProvider implementation:
886 bool GetUpstreamThroughputKbps(
887 int32_t* upstream_throughput_kbps) const override {
888 // NetworkQualityEstimator does not support upstream throughput.
889 ADD_FAILURE();
890 return false;
891 }
892
893 // ExternalEstimateProvider implementation:
894 bool GetTimeSinceLastUpdate(
895 base::TimeDelta* time_since_last_update) const override {
896 *time_since_last_update = time_since_last_update_;
897 get_time_since_last_update_count_++;
898 return true;
899 }
900
901 // ExternalEstimateProvider implementation:
902 void SetUpdatedEstimateDelegate(UpdatedEstimateDelegate* delegate) override {}
903
904 // ExternalEstimateProvider implementation:
905 void Update() const override { update_count_++; }
906
907 void set_time_since_last_update(base::TimeDelta time_since_last_update) {
908 time_since_last_update_ = time_since_last_update;
909 }
910
911 size_t get_time_since_last_update_count() const {
912 return get_time_since_last_update_count_;
913 }
914 size_t get_rtt_count() const { return get_rtt_count_; }
915 size_t get_downstream_throughput_kbps_count() const {
916 return get_downstream_throughput_kbps_count_;
917 }
918 size_t update_count() const { return update_count_; }
919
920 private:
921 // RTT and downstream throughput estimates.
922 const base::TimeDelta rtt_;
923 const int32_t downstream_throughput_kbps_;
924
925 base::TimeDelta time_since_last_update_;
926
927 // Keeps track of number of times different functions were called.
928 mutable size_t get_time_since_last_update_count_;
929 mutable size_t get_rtt_count_;
930 mutable size_t get_downstream_throughput_kbps_count_;
931 mutable size_t update_count_;
932
933 DISALLOW_COPY_AND_ASSIGN(TestExternalEstimateProvider);
934 };
935
936 // Tests if the external estimate provider is called in the constructor and
937 // on network change notification.
938 TEST(NetworkQualityEstimatorTest, TestExternalEstimateProvider) {
939 TestExternalEstimateProvider* test_external_estimate_provider =
940 new TestExternalEstimateProvider(base::TimeDelta::FromMilliseconds(1),
941 100);
942 scoped_ptr<ExternalEstimateProvider> external_estimate_provider(
943 test_external_estimate_provider);
944 std::map<std::string, std::string> variation_params;
945 TestNetworkQualityEstimator estimator(variation_params,
946 std::move(external_estimate_provider));
947
948 base::TimeDelta rtt;
949 int32_t kbps;
950 EXPECT_TRUE(estimator.GetURLRequestRTTEstimate(&rtt));
951 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
952
953 EXPECT_EQ(
954 1U, test_external_estimate_provider->get_time_since_last_update_count());
955 EXPECT_EQ(1U, test_external_estimate_provider->get_rtt_count());
956 EXPECT_EQ(
957 1U,
958 test_external_estimate_provider->get_downstream_throughput_kbps_count());
959
960 // Change network type to WiFi. Number of queries to External estimate
961 // provider must increment.
962 estimator.SimulateNetworkChangeTo(
963 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test-1");
964 EXPECT_TRUE(estimator.GetURLRequestRTTEstimate(&rtt));
965 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
966 EXPECT_EQ(
967 2U, test_external_estimate_provider->get_time_since_last_update_count());
968 EXPECT_EQ(2U, test_external_estimate_provider->get_rtt_count());
969 EXPECT_EQ(
970 2U,
971 test_external_estimate_provider->get_downstream_throughput_kbps_count());
972
973 // Change network type to 2G. Number of queries to External estimate provider
974 // must increment.
975 estimator.SimulateNetworkChangeTo(
976 NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test-1");
977 EXPECT_EQ(
978 3U, test_external_estimate_provider->get_time_since_last_update_count());
979 EXPECT_EQ(3U, test_external_estimate_provider->get_rtt_count());
980 EXPECT_EQ(
981 3U,
982 test_external_estimate_provider->get_downstream_throughput_kbps_count());
983
984 // Set the external estimate as old. Network Quality estimator should request
985 // an update on connection type change.
986 EXPECT_EQ(0U, test_external_estimate_provider->update_count());
987 test_external_estimate_provider->set_time_since_last_update(
988 base::TimeDelta::Max());
989
990 estimator.SimulateNetworkChangeTo(
991 NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test-2");
992 EXPECT_EQ(
993 4U, test_external_estimate_provider->get_time_since_last_update_count());
994 EXPECT_EQ(3U, test_external_estimate_provider->get_rtt_count());
995 EXPECT_EQ(
996 3U,
997 test_external_estimate_provider->get_downstream_throughput_kbps_count());
998 EXPECT_EQ(1U, test_external_estimate_provider->update_count());
999
1000 // Estimates are unavailable because external estimate provider never
1001 // notifies network quality estimator of the updated estimates.
1002 EXPECT_FALSE(estimator.GetURLRequestRTTEstimate(&rtt));
1003 EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
1004 }
1005
1006 // Tests if the estimate from the external estimate provider is merged with the
1007 // observations collected from the HTTP requests.
1008 TEST(NetworkQualityEstimatorTest, TestExternalEstimateProviderMergeEstimates) {
1009 const base::TimeDelta external_estimate_provider_rtt =
1010 base::TimeDelta::FromMilliseconds(1);
1011 const int32_t external_estimate_provider_downstream_throughput = 100;
1012 TestExternalEstimateProvider* test_external_estimate_provider =
1013 new TestExternalEstimateProvider(
1014 external_estimate_provider_rtt,
1015 external_estimate_provider_downstream_throughput);
1016 scoped_ptr<ExternalEstimateProvider> external_estimate_provider(
1017 test_external_estimate_provider);
1018
1019 std::map<std::string, std::string> variation_params;
1020 TestNetworkQualityEstimator estimator(variation_params,
1021 std::move(external_estimate_provider));
1022
1023 base::TimeDelta rtt;
1024 // Estimate provided by network quality estimator should match the estimate
1025 // provided by external estimate provider.
1026 EXPECT_TRUE(estimator.GetURLRequestRTTEstimate(&rtt));
1027 EXPECT_EQ(external_estimate_provider_rtt, rtt);
1028
1029 int32_t kbps;
1030 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
1031 EXPECT_EQ(external_estimate_provider_downstream_throughput, kbps);
1032
1033 EXPECT_EQ(1U, estimator.rtt_observations_.Size());
1034 EXPECT_EQ(1U, estimator.downstream_throughput_kbps_observations_.Size());
1035
1036 TestDelegate test_delegate;
1037 TestURLRequestContext context(true);
1038 context.set_network_quality_estimator(&estimator);
1039 context.Init();
1040
1041 scoped_ptr<URLRequest> request(context.CreateRequest(
1042 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate));
1043 request->Start();
1044 base::RunLoop().Run();
1045
1046 EXPECT_EQ(2U, estimator.rtt_observations_.Size());
1047 EXPECT_EQ(2U, estimator.downstream_throughput_kbps_observations_.Size());
1048 }
1049
1050 TEST(NetworkQualityEstimatorTest, TestObservers) {
1051 TestRTTObserver rtt_observer;
1052 TestThroughputObserver throughput_observer;
1053 std::map<std::string, std::string> variation_params;
1054 TestNetworkQualityEstimator estimator(variation_params);
1055 estimator.AddRTTObserver(&rtt_observer);
1056 estimator.AddThroughputObserver(&throughput_observer);
1057
1058 TestDelegate test_delegate;
1059 TestURLRequestContext context(true);
1060 context.set_network_quality_estimator(&estimator);
1061 context.Init();
1062
1063 EXPECT_EQ(0U, rtt_observer.observations().size());
1064 EXPECT_EQ(0U, throughput_observer.observations().size());
1065 base::TimeTicks then = base::TimeTicks::Now();
1066
1067 scoped_ptr<URLRequest> request(context.CreateRequest(
1068 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate));
1069 request->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME);
1070 request->Start();
1071 base::RunLoop().Run();
1072
1073 scoped_ptr<URLRequest> request2(context.CreateRequest(
1074 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate));
1075 request2->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME);
1076 request2->Start();
1077 base::RunLoop().Run();
1078
1079 // Both RTT and downstream throughput should be updated.
1080 base::TimeDelta rtt;
1081 EXPECT_TRUE(estimator.GetURLRequestRTTEstimate(&rtt));
1082
1083 int32_t throughput;
1084 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&throughput));
1085
1086 EXPECT_EQ(2U, rtt_observer.observations().size());
1087 EXPECT_EQ(2U, throughput_observer.observations().size());
1088 for (auto observation : rtt_observer.observations()) {
1089 EXPECT_LE(0, observation.rtt_ms);
1090 EXPECT_LE(0, (observation.timestamp - then).InMilliseconds());
1091 EXPECT_EQ(NetworkQualityEstimator::URL_REQUEST, observation.source);
1092 }
1093 for (auto observation : throughput_observer.observations()) {
1094 EXPECT_LE(0, observation.throughput_kbps);
1095 EXPECT_LE(0, (observation.timestamp - then).InMilliseconds());
1096 EXPECT_EQ(NetworkQualityEstimator::URL_REQUEST, observation.source);
1097 }
1098
1099 // Verify that observations from TCP and QUIC are passed on to the observers.
1100 base::TimeDelta tcp_rtt(base::TimeDelta::FromMilliseconds(1));
1101 base::TimeDelta quic_rtt(base::TimeDelta::FromMilliseconds(2));
1102
1103 scoped_ptr<SocketPerformanceWatcher> tcp_watcher =
1104 estimator.GetSocketPerformanceWatcherFactory()
1105 ->CreateSocketPerformanceWatcher(
1106 SocketPerformanceWatcherFactory::PROTOCOL_TCP);
1107
1108 scoped_ptr<SocketPerformanceWatcher> quic_watcher =
1109 estimator.GetSocketPerformanceWatcherFactory()
1110 ->CreateSocketPerformanceWatcher(
1111 SocketPerformanceWatcherFactory::PROTOCOL_QUIC);
1112
1113 tcp_watcher->OnUpdatedRTTAvailable(tcp_rtt);
1114 quic_watcher->OnUpdatedRTTAvailable(quic_rtt);
1115
1116 base::RunLoop().RunUntilIdle();
1117
1118 EXPECT_EQ(4U, rtt_observer.observations().size());
1119 EXPECT_EQ(2U, throughput_observer.observations().size());
1120
1121 EXPECT_EQ(tcp_rtt.InMilliseconds(), rtt_observer.observations().at(2).rtt_ms);
1122 EXPECT_EQ(quic_rtt.InMilliseconds(),
1123 rtt_observer.observations().at(3).rtt_ms);
1124 }
1125
1126 // TestTCPSocketRTT requires kernel support for tcp_info struct, and so it is
1127 // enabled only on certain platforms.
1128 #if defined(TCP_INFO) || defined(OS_LINUX)
1129 #define MAYBE_TestTCPSocketRTT TestTCPSocketRTT
1130 #else
1131 #define MAYBE_TestTCPSocketRTT DISABLED_TestTCPSocketRTT
1132 #endif
1133 // Tests that the TCP socket notifies the Network Quality Estimator of TCP RTTs,
1134 // which in turn notifies registered RTT observers.
1135 TEST(NetworkQualityEstimatorTest, MAYBE_TestTCPSocketRTT) {
1136 TestRTTObserver rtt_observer;
1137 std::map<std::string, std::string> variation_params;
1138 TestNetworkQualityEstimator estimator(variation_params);
1139 estimator.AddRTTObserver(&rtt_observer);
1140
1141 TestDelegate test_delegate;
1142 TestURLRequestContext context(true);
1143 context.set_network_quality_estimator(&estimator);
1144
1145 scoped_ptr<HttpNetworkSession::Params> params(new HttpNetworkSession::Params);
1146 // |estimator| should be notified of TCP RTT observations.
1147 params->socket_performance_watcher_factory =
1148 estimator.GetSocketPerformanceWatcherFactory();
1149 context.set_http_network_session_params(std::move(params));
1150 context.Init();
1151
1152 EXPECT_EQ(0U, rtt_observer.observations().size());
1153
1154 // Send two requests. Verify that the completion of each request generates at
1155 // least one TCP RTT observation.
1156 for (size_t i = 0; i < 2; ++i) {
1157 size_t before_count_tcp_rtt_observations = 0;
1158 for (const auto& observation : rtt_observer.observations()) {
1159 if (observation.source == NetworkQualityEstimator::TCP)
1160 ++before_count_tcp_rtt_observations;
1161 }
1162
1163 scoped_ptr<URLRequest> request(context.CreateRequest(
1164 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate));
1165 request->Start();
1166 base::RunLoop().Run();
1167
1168 size_t after_count_tcp_rtt_observations = 0;
1169 for (const auto& observation : rtt_observer.observations()) {
1170 if (observation.source == NetworkQualityEstimator::TCP)
1171 ++after_count_tcp_rtt_observations;
1172 }
1173 // At least one notification should be received per socket performance
1174 // watcher.
1175 EXPECT_LE(1U, after_count_tcp_rtt_observations -
1176 before_count_tcp_rtt_observations)
1177 << i;
1178 }
1179 }
1180
1181 } // namespace net
OLDNEW

Powered by Google App Engine
This is Rietveld 408576698