Record accuracy rate for Lo-Fi.
[chromium-blink-merge.git] / net / base / network_quality_estimator_unittest.cc
blob6790bb7637b6dae14fff943c90f447bd0a14c3b0
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.
5 #include "net/base/network_quality_estimator.h"
7 #include <stdint.h>
9 #include <limits>
10 #include <map>
12 #include "base/basictypes.h"
13 #include "base/logging.h"
14 #include "base/memory/scoped_ptr.h"
15 #include "base/metrics/histogram_samples.h"
16 #include "base/run_loop.h"
17 #include "base/strings/string_number_conversions.h"
18 #include "base/test/histogram_tester.h"
19 #include "base/time/time.h"
20 #include "build/build_config.h"
21 #include "net/base/external_estimate_provider.h"
22 #include "net/base/load_flags.h"
23 #include "net/base/network_change_notifier.h"
24 #include "net/test/embedded_test_server/embedded_test_server.h"
25 #include "net/url_request/url_request_test_util.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "url/gurl.h"
29 namespace {
31 // Helps in setting the current network type and id.
32 class TestNetworkQualityEstimator : public net::NetworkQualityEstimator {
33 public:
34 TestNetworkQualityEstimator(
35 const std::map<std::string, std::string>& variation_params)
36 : NetworkQualityEstimator(scoped_ptr<net::ExternalEstimateProvider>(),
37 variation_params,
38 true,
39 true) {}
41 ~TestNetworkQualityEstimator() override {}
43 // Overrides the current network type and id.
44 // Notifies network quality estimator of change in connection.
45 void SimulateNetworkChangeTo(net::NetworkChangeNotifier::ConnectionType type,
46 std::string network_id) {
47 current_network_type_ = type;
48 current_network_id_ = network_id;
49 OnConnectionTypeChanged(type);
52 using NetworkQualityEstimator::ReadCachedNetworkQualityEstimate;
53 using NetworkQualityEstimator::OnConnectionTypeChanged;
55 private:
56 // NetworkQualityEstimator implementation that returns the overridden network
57 // id (instead of invoking platform APIs).
58 NetworkQualityEstimator::NetworkID GetCurrentNetworkID() const override {
59 return NetworkQualityEstimator::NetworkID(current_network_type_,
60 current_network_id_);
63 net::NetworkChangeNotifier::ConnectionType current_network_type_;
64 std::string current_network_id_;
67 } // namespace
69 namespace net {
71 TEST(NetworkQualityEstimatorTest, TestKbpsRTTUpdates) {
72 net::test_server::EmbeddedTestServer embedded_test_server;
73 embedded_test_server.ServeFilesFromDirectory(
74 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest")));
75 ASSERT_TRUE(embedded_test_server.InitializeAndWaitUntilReady());
77 base::HistogramTester histogram_tester;
78 // Enable requests to local host to be used for network quality estimation.
79 std::map<std::string, std::string> variation_params;
80 TestNetworkQualityEstimator estimator(variation_params);
82 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(),
83 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100));
84 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput,
85 estimator.GetDownlinkThroughputKbpsEstimateInternal(
86 base::TimeTicks(), 100));
88 TestDelegate test_delegate;
89 TestURLRequestContext context(false);
91 scoped_ptr<URLRequest> request(
92 context.CreateRequest(embedded_test_server.GetURL("/echo.html"),
93 DEFAULT_PRIORITY, &test_delegate));
94 request->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME);
95 request->Start();
97 base::RunLoop().Run();
99 // Both RTT and downstream throughput should be updated.
100 estimator.NotifyHeadersReceived(*request);
101 estimator.NotifyRequestCompleted(*request);
102 EXPECT_NE(NetworkQualityEstimator::InvalidRTT(),
103 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100));
104 EXPECT_NE(NetworkQualityEstimator::kInvalidThroughput,
105 estimator.GetDownlinkThroughputKbpsEstimateInternal(
106 base::TimeTicks(), 100));
108 base::TimeDelta rtt = NetworkQualityEstimator::InvalidRTT();
109 int32_t kbps = NetworkQualityEstimator::kInvalidThroughput;
110 EXPECT_TRUE(estimator.GetRTTEstimate(&rtt));
111 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
112 EXPECT_NE(NetworkQualityEstimator::InvalidRTT(), rtt);
113 EXPECT_NE(NetworkQualityEstimator::kInvalidThroughput, kbps);
115 EXPECT_NEAR(
116 rtt.InMilliseconds(),
117 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100).InMilliseconds(),
120 // Check UMA histograms.
121 histogram_tester.ExpectTotalCount("NQE.PeakKbps.Unknown", 0);
122 histogram_tester.ExpectTotalCount("NQE.FastestRTT.Unknown", 0);
124 histogram_tester.ExpectTotalCount("NQE.RatioEstimatedToActualRTT.Unknown", 0);
126 estimator.NotifyHeadersReceived(*request);
127 estimator.NotifyRequestCompleted(*request);
128 histogram_tester.ExpectTotalCount("NQE.RTTObservations.Unknown", 1);
129 estimator.SimulateNetworkChangeTo(
130 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test-1");
131 histogram_tester.ExpectTotalCount("NQE.PeakKbps.Unknown", 1);
132 histogram_tester.ExpectTotalCount("NQE.FastestRTT.Unknown", 1);
134 histogram_tester.ExpectTotalCount("NQE.RatioMedianRTT.WiFi", 0);
136 histogram_tester.ExpectTotalCount("NQE.RTT.Percentile0.Unknown", 1);
137 histogram_tester.ExpectTotalCount("NQE.RTT.Percentile10.Unknown", 1);
138 histogram_tester.ExpectTotalCount("NQE.RTT.Percentile50.Unknown", 1);
139 histogram_tester.ExpectTotalCount("NQE.RTT.Percentile90.Unknown", 1);
140 histogram_tester.ExpectTotalCount("NQE.RTT.Percentile100.Unknown", 1);
142 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(),
143 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100));
144 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput,
145 estimator.GetDownlinkThroughputKbpsEstimateInternal(
146 base::TimeTicks(), 100));
148 EXPECT_FALSE(estimator.GetRTTEstimate(&rtt));
149 EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
150 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(), rtt);
151 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput, kbps);
153 estimator.SimulateNetworkChangeTo(
154 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, std::string());
155 histogram_tester.ExpectTotalCount("NQE.PeakKbps.Unknown", 1);
156 histogram_tester.ExpectTotalCount("NQE.FastestRTT.Unknown", 1);
158 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(),
159 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100));
160 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput,
161 estimator.GetDownlinkThroughputKbpsEstimateInternal(
162 base::TimeTicks(), 100));
164 EXPECT_FALSE(estimator.GetRTTEstimate(&rtt));
165 EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
168 TEST(NetworkQualityEstimatorTest, StoreObservations) {
169 net::test_server::EmbeddedTestServer embedded_test_server;
170 embedded_test_server.ServeFilesFromDirectory(
171 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest")));
172 ASSERT_TRUE(embedded_test_server.InitializeAndWaitUntilReady());
174 std::map<std::string, std::string> variation_params;
175 TestNetworkQualityEstimator estimator(variation_params);
176 TestDelegate test_delegate;
177 TestURLRequestContext context(false);
179 // Push 10 more observations than the maximum buffer size.
180 for (size_t i = 0; i < estimator.kMaximumObservationsBufferSize + 10U; ++i) {
181 scoped_ptr<URLRequest> request(
182 context.CreateRequest(embedded_test_server.GetURL("/echo.html"),
183 DEFAULT_PRIORITY, &test_delegate));
184 request->Start();
185 base::RunLoop().Run();
187 estimator.NotifyHeadersReceived(*request);
188 estimator.NotifyRequestCompleted(*request);
191 EXPECT_EQ(static_cast<size_t>(
192 NetworkQualityEstimator::kMaximumObservationsBufferSize),
193 estimator.downstream_throughput_kbps_observations_.Size());
194 EXPECT_EQ(static_cast<size_t>(
195 NetworkQualityEstimator::kMaximumObservationsBufferSize),
196 estimator.rtt_msec_observations_.Size());
198 // Verify that the stored observations are cleared on network change.
199 estimator.SimulateNetworkChangeTo(
200 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test-2");
201 EXPECT_EQ(0U, estimator.downstream_throughput_kbps_observations_.Size());
202 EXPECT_EQ(0U, estimator.rtt_msec_observations_.Size());
204 scoped_ptr<URLRequest> request(
205 context.CreateRequest(embedded_test_server.GetURL("/echo.html"),
206 DEFAULT_PRIORITY, &test_delegate));
209 // Verifies that the percentiles are correctly computed. All observations have
210 // the same timestamp. Kbps percentiles must be in decreasing order. RTT
211 // percentiles must be in increasing order.
212 TEST(NetworkQualityEstimatorTest, PercentileSameTimestamps) {
213 std::map<std::string, std::string> variation_params;
214 TestNetworkQualityEstimator estimator(variation_params);
215 base::TimeTicks now = base::TimeTicks::Now();
217 // Network quality should be unavailable when no observations are available.
218 base::TimeDelta rtt;
219 EXPECT_FALSE(estimator.GetRTTEstimate(&rtt));
220 int32_t kbps;
221 EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
223 // Insert samples from {1,2,3,..., 100}. First insert odd samples, then even
224 // samples. This helps in verifying that the order of samples does not matter.
225 for (int i = 1; i <= 99; i += 2) {
226 estimator.downstream_throughput_kbps_observations_.AddObservation(
227 NetworkQualityEstimator::Observation(i, now));
228 estimator.rtt_msec_observations_.AddObservation(
229 NetworkQualityEstimator::Observation(i, now));
230 EXPECT_TRUE(estimator.GetRTTEstimate(&rtt));
231 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
234 for (int i = 2; i <= 100; i += 2) {
235 estimator.downstream_throughput_kbps_observations_.AddObservation(
236 NetworkQualityEstimator::Observation(i, now));
237 estimator.rtt_msec_observations_.AddObservation(
238 NetworkQualityEstimator::Observation(i, now));
239 EXPECT_TRUE(estimator.GetRTTEstimate(&rtt));
240 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
243 for (int i = 0; i <= 100; ++i) {
244 // Checks if the difference between the two integers is less than 1. This is
245 // required because computed percentiles may be slightly different from
246 // what is expected due to floating point computation errors and integer
247 // rounding off errors.
248 EXPECT_NEAR(estimator.GetDownlinkThroughputKbpsEstimateInternal(
249 base::TimeTicks(), i),
250 100 - i, 1);
251 EXPECT_NEAR(
252 estimator.GetRTTEstimateInternal(base::TimeTicks(), i).InMilliseconds(),
253 i, 1);
256 EXPECT_TRUE(estimator.GetRTTEstimate(&rtt));
257 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
258 // |network_quality| should be equal to the 50 percentile value.
259 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimateInternal(
260 base::TimeTicks(), 50) > 0);
261 EXPECT_TRUE(estimator.GetRTTEstimateInternal(base::TimeTicks(), 50) !=
262 NetworkQualityEstimator::InvalidRTT());
265 // Verifies that the percentiles are correctly computed. Observations have
266 // different timestamps with half the observations being very old and the rest
267 // of them being very recent. Percentiles should factor in recent observations
268 // much more heavily than older samples. Kbps percentiles must be in decreasing
269 // order. RTT percentiles must be in increasing order.
270 TEST(NetworkQualityEstimatorTest, PercentileDifferentTimestamps) {
271 std::map<std::string, std::string> variation_params;
272 TestNetworkQualityEstimator estimator(variation_params);
273 base::TimeTicks now = base::TimeTicks::Now();
274 base::TimeTicks very_old = base::TimeTicks::UnixEpoch();
276 // First 50 samples have very old timestamp.
277 for (int i = 1; i <= 50; ++i) {
278 estimator.downstream_throughput_kbps_observations_.AddObservation(
279 NetworkQualityEstimator::Observation(i, very_old));
280 estimator.rtt_msec_observations_.AddObservation(
281 NetworkQualityEstimator::Observation(i, very_old));
284 // Next 50 (i.e., from 51 to 100) have recent timestamp.
285 for (int i = 51; i <= 100; ++i) {
286 estimator.downstream_throughput_kbps_observations_.AddObservation(
287 NetworkQualityEstimator::Observation(i, now));
288 estimator.rtt_msec_observations_.AddObservation(
289 NetworkQualityEstimator::Observation(i, now));
292 // Older samples have very little weight. So, all percentiles are >= 51
293 // (lowest value among recent observations).
294 for (int i = 1; i < 100; ++i) {
295 // Checks if the difference between the two integers is less than 1. This is
296 // required because computed percentiles may be slightly different from
297 // what is expected due to floating point computation errors and integer
298 // rounding off errors.
299 EXPECT_NEAR(estimator.GetDownlinkThroughputKbpsEstimateInternal(
300 base::TimeTicks(), i),
301 51 + 0.49 * (100 - i), 1);
302 EXPECT_NEAR(
303 estimator.GetRTTEstimateInternal(base::TimeTicks(), i).InMilliseconds(),
304 51 + 0.49 * i, 1);
307 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(),
308 estimator.GetRTTEstimateInternal(
309 base::TimeTicks::Now() + base::TimeDelta::FromMinutes(10), 50));
310 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput,
311 estimator.GetDownlinkThroughputKbpsEstimateInternal(
312 base::TimeTicks::Now() + base::TimeDelta::FromMinutes(10), 50));
315 // This test notifies NetworkQualityEstimator of received data. Next,
316 // throughput and RTT percentiles are checked for correctness by doing simple
317 // verifications.
318 TEST(NetworkQualityEstimatorTest, ComputedPercentiles) {
319 net::test_server::EmbeddedTestServer embedded_test_server;
320 embedded_test_server.ServeFilesFromDirectory(
321 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest")));
322 ASSERT_TRUE(embedded_test_server.InitializeAndWaitUntilReady());
324 std::map<std::string, std::string> variation_params;
325 TestNetworkQualityEstimator estimator(variation_params);
327 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(),
328 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100));
329 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput,
330 estimator.GetDownlinkThroughputKbpsEstimateInternal(
331 base::TimeTicks(), 100));
333 TestDelegate test_delegate;
334 TestURLRequestContext context(false);
336 // Number of observations are more than the maximum buffer size.
337 for (size_t i = 0; i < estimator.kMaximumObservationsBufferSize + 100U; ++i) {
338 scoped_ptr<URLRequest> request(
339 context.CreateRequest(embedded_test_server.GetURL("/echo.html"),
340 DEFAULT_PRIORITY, &test_delegate));
341 request->Start();
342 base::RunLoop().Run();
344 // Use different number of bytes to create variation.
345 estimator.NotifyHeadersReceived(*request);
346 estimator.NotifyRequestCompleted(*request);
349 // Verify the percentiles through simple tests.
350 for (int i = 0; i <= 100; ++i) {
351 EXPECT_GT(estimator.GetDownlinkThroughputKbpsEstimateInternal(
352 base::TimeTicks(), i),
354 EXPECT_LT(estimator.GetRTTEstimateInternal(base::TimeTicks(), i),
355 base::TimeDelta::Max());
357 if (i != 0) {
358 // Throughput percentiles are in decreasing order.
359 EXPECT_LE(estimator.GetDownlinkThroughputKbpsEstimateInternal(
360 base::TimeTicks(), i),
361 estimator.GetDownlinkThroughputKbpsEstimateInternal(
362 base::TimeTicks(), i - 1));
364 // RTT percentiles are in increasing order.
365 EXPECT_GE(estimator.GetRTTEstimateInternal(base::TimeTicks(), i),
366 estimator.GetRTTEstimateInternal(base::TimeTicks(), i - 1));
371 TEST(NetworkQualityEstimatorTest, ObtainOperatingParams) {
372 std::map<std::string, std::string> variation_params;
373 variation_params["Unknown.DefaultMedianKbps"] = "100";
374 variation_params["WiFi.DefaultMedianKbps"] = "200";
375 variation_params["2G.DefaultMedianKbps"] = "300";
377 variation_params["Unknown.DefaultMedianRTTMsec"] = "1000";
378 variation_params["WiFi.DefaultMedianRTTMsec"] = "2000";
379 // Negative variation value should not be used.
380 variation_params["2G.DefaultMedianRTTMsec"] = "-5";
382 TestNetworkQualityEstimator estimator(variation_params);
383 EXPECT_EQ(1U, estimator.downstream_throughput_kbps_observations_.Size());
384 EXPECT_EQ(1U, estimator.rtt_msec_observations_.Size());
386 base::TimeDelta rtt;
387 EXPECT_TRUE(estimator.GetRTTEstimate(&rtt));
388 int32_t kbps;
389 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
391 EXPECT_EQ(100, kbps);
392 EXPECT_EQ(base::TimeDelta::FromMilliseconds(1000), rtt);
393 auto it =
394 estimator.downstream_throughput_kbps_observations_.observations_.begin();
395 EXPECT_EQ(100, (*it).value);
396 it = estimator.rtt_msec_observations_.observations_.begin();
397 EXPECT_EQ(1000, (*it).value);
399 // Simulate network change to Wi-Fi.
400 estimator.SimulateNetworkChangeTo(
401 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test-1");
402 EXPECT_EQ(1U, estimator.downstream_throughput_kbps_observations_.Size());
403 EXPECT_EQ(1U, estimator.rtt_msec_observations_.Size());
405 EXPECT_TRUE(estimator.GetRTTEstimate(&rtt));
406 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
407 EXPECT_EQ(200, kbps);
408 EXPECT_EQ(base::TimeDelta::FromMilliseconds(2000), rtt);
410 it = estimator.downstream_throughput_kbps_observations_.observations_.begin();
411 EXPECT_EQ(200, (*it).value);
412 it = estimator.rtt_msec_observations_.observations_.begin();
413 EXPECT_EQ(2000, (*it).value);
415 // Peak network quality should not be affected by the network quality
416 // estimator field trial.
417 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(),
418 estimator.peak_network_quality_.rtt());
419 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput,
420 estimator.peak_network_quality_.downstream_throughput_kbps());
422 // Simulate network change to 2G. Only the Kbps default estimate should be
423 // available.
424 estimator.SimulateNetworkChangeTo(
425 NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test-2");
426 EXPECT_EQ(1U, estimator.downstream_throughput_kbps_observations_.Size());
427 EXPECT_EQ(0U, estimator.rtt_msec_observations_.Size());
429 EXPECT_FALSE(estimator.GetRTTEstimate(&rtt));
430 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
432 it = estimator.downstream_throughput_kbps_observations_.observations_.begin();
433 EXPECT_EQ(300, (*it).value);
435 // Simulate network change to 3G. Default estimates should be unavailable.
436 estimator.SimulateNetworkChangeTo(
437 NetworkChangeNotifier::ConnectionType::CONNECTION_3G, "test-3");
439 EXPECT_FALSE(estimator.GetRTTEstimate(&rtt));
440 EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
441 EXPECT_EQ(0U, estimator.downstream_throughput_kbps_observations_.Size());
442 EXPECT_EQ(0U, estimator.rtt_msec_observations_.Size());
445 TEST(NetworkQualityEstimatorTest, HalfLifeParam) {
446 // Verifies if |weight_multiplier_per_second_| is set to correct value for
447 // various values of half life parameter.
448 std::map<std::string, std::string> variation_params;
450 // Half life parameter is not set. Default value of
451 // |weight_multiplier_per_second_| should be used.
452 TestNetworkQualityEstimator estimator(variation_params);
453 EXPECT_NEAR(0.988, estimator.downstream_throughput_kbps_observations_
454 .weight_multiplier_per_second_,
455 0.001);
458 variation_params["HalfLifeSeconds"] = "-100";
460 // Half life parameter is set to a negative value. Default value of
461 // |weight_multiplier_per_second_| should be used.
462 TestNetworkQualityEstimator estimator(variation_params);
463 EXPECT_NEAR(0.988, estimator.downstream_throughput_kbps_observations_
464 .weight_multiplier_per_second_,
465 0.001);
468 variation_params["HalfLifeSeconds"] = "0";
470 // Half life parameter is set to zero. Default value of
471 // |weight_multiplier_per_second_| should be used.
472 TestNetworkQualityEstimator estimator(variation_params);
473 EXPECT_NEAR(0.988, estimator.downstream_throughput_kbps_observations_
474 .weight_multiplier_per_second_,
475 0.001);
478 variation_params["HalfLifeSeconds"] = "10";
480 // Half life parameter is set to a valid value.
481 TestNetworkQualityEstimator estimator(variation_params);
482 EXPECT_NEAR(0.933, estimator.downstream_throughput_kbps_observations_
483 .weight_multiplier_per_second_,
484 0.001);
488 // Test if the network estimates are cached when network change notification
489 // is invoked.
490 TEST(NetworkQualityEstimatorTest, TestCaching) {
491 std::map<std::string, std::string> variation_params;
492 TestNetworkQualityEstimator estimator(variation_params);
493 size_t expected_cache_size = 0;
494 EXPECT_EQ(expected_cache_size, estimator.cached_network_qualities_.size());
496 // Cache entry will not be added for (NONE, "").
497 estimator.downstream_throughput_kbps_observations_.AddObservation(
498 NetworkQualityEstimator::Observation(1, base::TimeTicks::Now()));
499 estimator.rtt_msec_observations_.AddObservation(
500 NetworkQualityEstimator::Observation(1000, base::TimeTicks::Now()));
501 estimator.SimulateNetworkChangeTo(
502 NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test-1");
503 EXPECT_EQ(expected_cache_size, estimator.cached_network_qualities_.size());
505 // Entry will be added for (2G, "test1").
506 // Also, set the network quality for (2G, "test1") so that it is stored in
507 // the cache.
508 estimator.downstream_throughput_kbps_observations_.AddObservation(
509 NetworkQualityEstimator::Observation(1, base::TimeTicks::Now()));
510 estimator.rtt_msec_observations_.AddObservation(
511 NetworkQualityEstimator::Observation(1000, base::TimeTicks::Now()));
513 estimator.SimulateNetworkChangeTo(
514 NetworkChangeNotifier::ConnectionType::CONNECTION_3G, "test-1");
515 EXPECT_EQ(++expected_cache_size, estimator.cached_network_qualities_.size());
517 // Entry will be added for (3G, "test1").
518 // Also, set the network quality for (3G, "test1") so that it is stored in
519 // the cache.
520 estimator.downstream_throughput_kbps_observations_.AddObservation(
521 NetworkQualityEstimator::Observation(2, base::TimeTicks::Now()));
522 estimator.rtt_msec_observations_.AddObservation(
523 NetworkQualityEstimator::Observation(500, base::TimeTicks::Now()));
524 estimator.SimulateNetworkChangeTo(
525 NetworkChangeNotifier::ConnectionType::CONNECTION_3G, "test-2");
526 EXPECT_EQ(++expected_cache_size, estimator.cached_network_qualities_.size());
528 // Entry will not be added for (3G, "test2").
529 estimator.SimulateNetworkChangeTo(
530 NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test-1");
531 EXPECT_EQ(expected_cache_size, estimator.cached_network_qualities_.size());
533 // Read the network quality for (2G, "test-1").
534 EXPECT_TRUE(estimator.ReadCachedNetworkQualityEstimate());
536 base::TimeDelta rtt;
537 int32_t kbps;
538 EXPECT_TRUE(estimator.GetRTTEstimate(&rtt));
539 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
540 EXPECT_EQ(1, kbps);
541 EXPECT_EQ(base::TimeDelta::FromMilliseconds(1000), rtt);
542 // No new entry should be added for (2G, "test-1") since it already exists
543 // in the cache.
544 estimator.SimulateNetworkChangeTo(
545 NetworkChangeNotifier::ConnectionType::CONNECTION_3G, "test-1");
546 EXPECT_EQ(expected_cache_size, estimator.cached_network_qualities_.size());
548 // Read the network quality for (3G, "test-1").
549 EXPECT_TRUE(estimator.ReadCachedNetworkQualityEstimate());
550 EXPECT_TRUE(estimator.GetRTTEstimate(&rtt));
551 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
552 EXPECT_EQ(2, kbps);
553 EXPECT_EQ(base::TimeDelta::FromMilliseconds(500), rtt);
554 // No new entry should be added for (3G, "test1") since it already exists
555 // in the cache.
556 estimator.SimulateNetworkChangeTo(
557 NetworkChangeNotifier::ConnectionType::CONNECTION_3G, "test-2");
558 EXPECT_EQ(expected_cache_size, estimator.cached_network_qualities_.size());
560 // Reading quality of (3G, "test-2") should return false.
561 EXPECT_FALSE(estimator.ReadCachedNetworkQualityEstimate());
563 // Reading quality of (2G, "test-3") should return false.
564 estimator.SimulateNetworkChangeTo(
565 NetworkChangeNotifier::ConnectionType::CONNECTION_2G, "test-3");
566 EXPECT_FALSE(estimator.ReadCachedNetworkQualityEstimate());
569 // Tests if the cache size remains bounded. Also, ensure that the cache is
570 // LRU.
571 TEST(NetworkQualityEstimatorTest, TestLRUCacheMaximumSize) {
572 std::map<std::string, std::string> variation_params;
573 TestNetworkQualityEstimator estimator(variation_params);
574 estimator.SimulateNetworkChangeTo(
575 net::NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI,
576 std::string());
577 EXPECT_EQ(0U, estimator.cached_network_qualities_.size());
579 // Add 100 more networks than the maximum size of the cache.
580 size_t network_count =
581 NetworkQualityEstimator::kMaximumNetworkQualityCacheSize + 100;
583 base::TimeTicks update_time_of_network_100;
584 for (size_t i = 0; i < network_count; ++i) {
585 estimator.downstream_throughput_kbps_observations_.AddObservation(
586 NetworkQualityEstimator::Observation(2, base::TimeTicks::Now()));
587 estimator.rtt_msec_observations_.AddObservation(
588 NetworkQualityEstimator::Observation(500, base::TimeTicks::Now()));
590 if (i == 100)
591 update_time_of_network_100 = base::TimeTicks::Now();
593 estimator.SimulateNetworkChangeTo(
594 net::NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI,
595 base::IntToString(i));
596 if (i < NetworkQualityEstimator::kMaximumNetworkQualityCacheSize)
597 EXPECT_EQ(i, estimator.cached_network_qualities_.size());
598 EXPECT_LE(estimator.cached_network_qualities_.size(),
599 static_cast<size_t>(
600 NetworkQualityEstimator::kMaximumNetworkQualityCacheSize));
602 // One more call so that the last network is also written to cache.
603 estimator.downstream_throughput_kbps_observations_.AddObservation(
604 NetworkQualityEstimator::Observation(2, base::TimeTicks::Now()));
605 estimator.rtt_msec_observations_.AddObservation(
606 NetworkQualityEstimator::Observation(500, base::TimeTicks::Now()));
607 estimator.SimulateNetworkChangeTo(
608 net::NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI,
609 base::IntToString(network_count - 1));
610 EXPECT_EQ(static_cast<size_t>(
611 NetworkQualityEstimator::kMaximumNetworkQualityCacheSize),
612 estimator.cached_network_qualities_.size());
614 // Test that the cache is LRU by examining its contents. Networks in cache
615 // must all be newer than the 100th network.
616 for (NetworkQualityEstimator::CachedNetworkQualities::iterator it =
617 estimator.cached_network_qualities_.begin();
618 it != estimator.cached_network_qualities_.end(); ++it) {
619 EXPECT_GE((it->second).last_update_time_, update_time_of_network_100);
623 TEST(NetworkQualityEstimatorTest, TestGetMedianRTTSince) {
624 std::map<std::string, std::string> variation_params;
625 TestNetworkQualityEstimator estimator(variation_params);
626 base::TimeTicks now = base::TimeTicks::Now();
627 base::TimeTicks old =
628 base::TimeTicks::Now() - base::TimeDelta::FromMilliseconds(1);
630 // First sample has very old timestamp.
631 estimator.downstream_throughput_kbps_observations_.AddObservation(
632 NetworkQualityEstimator::Observation(1, old));
633 estimator.rtt_msec_observations_.AddObservation(
634 NetworkQualityEstimator::Observation(1, old));
636 estimator.downstream_throughput_kbps_observations_.AddObservation(
637 NetworkQualityEstimator::Observation(100, now));
638 estimator.rtt_msec_observations_.AddObservation(
639 NetworkQualityEstimator::Observation(100, now));
641 base::TimeDelta rtt;
642 EXPECT_FALSE(estimator.GetRecentMedianRTT(
643 now + base::TimeDelta::FromSeconds(10), &rtt));
644 EXPECT_TRUE(estimator.GetRecentMedianRTT(now, &rtt));
645 EXPECT_EQ(100, rtt.InMilliseconds());
647 int32_t downstream_throughput_kbps;
648 EXPECT_FALSE(estimator.GetRecentMedianDownlinkThroughputKbps(
649 now + base::TimeDelta::FromSeconds(10), &downstream_throughput_kbps));
650 EXPECT_TRUE(estimator.GetRecentMedianDownlinkThroughputKbps(
651 now, &downstream_throughput_kbps));
652 EXPECT_EQ(100, downstream_throughput_kbps);
655 } // namespace net