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"
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"
31 // Helps in setting the current network type and id.
32 class TestNetworkQualityEstimator
: public net::NetworkQualityEstimator
{
34 TestNetworkQualityEstimator(
35 const std::map
<std::string
, std::string
>& variation_params
)
36 : NetworkQualityEstimator(scoped_ptr
<net::ExternalEstimateProvider
>(),
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
;
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_
,
63 net::NetworkChangeNotifier::ConnectionType current_network_type_
;
64 std::string current_network_id_
;
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
);
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
);
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
));
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.
219 EXPECT_FALSE(estimator
.GetRTTEstimate(&rtt
));
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
),
252 estimator
.GetRTTEstimateInternal(base::TimeTicks(), i
).InMilliseconds(),
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);
303 estimator
.GetRTTEstimateInternal(base::TimeTicks(), i
).InMilliseconds(),
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
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
));
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());
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());
387 EXPECT_TRUE(estimator
.GetRTTEstimate(&rtt
));
389 EXPECT_TRUE(estimator
.GetDownlinkThroughputKbpsEstimate(&kbps
));
391 EXPECT_EQ(100, kbps
);
392 EXPECT_EQ(base::TimeDelta::FromMilliseconds(1000), rtt
);
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
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_
,
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_
,
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_
,
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_
,
488 // Test if the network estimates are cached when network change notification
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
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
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());
538 EXPECT_TRUE(estimator
.GetRTTEstimate(&rtt
));
539 EXPECT_TRUE(estimator
.GetDownlinkThroughputKbpsEstimate(&kbps
));
541 EXPECT_EQ(base::TimeDelta::FromMilliseconds(1000), rtt
);
542 // No new entry should be added for (2G, "test-1") since it already exists
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
));
553 EXPECT_EQ(base::TimeDelta::FromMilliseconds(500), rtt
);
554 // No new entry should be added for (3G, "test1") since it already exists
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
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
,
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()));
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(),
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
));
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
);