OLD | NEW |
1 // Copyright 2015 The Chromium Authors. All rights reserved. | 1 // Copyright 2015 The Chromium Authors. All rights reserved. |
2 // Use of this source code is governed by a BSD-style license that can be | 2 // Use of this source code is governed by a BSD-style license that can be |
3 // found in the LICENSE file. | 3 // found in the LICENSE file. |
4 | 4 |
5 #include "net/base/network_quality_estimator.h" | 5 #include "net/base/network_quality_estimator.h" |
6 | 6 |
| 7 #include <stddef.h> |
7 #include <stdint.h> | 8 #include <stdint.h> |
| 9 |
8 #include <limits> | 10 #include <limits> |
9 #include <map> | 11 #include <map> |
| 12 #include <string> |
10 #include <utility> | 13 #include <utility> |
11 #include <vector> | 14 #include <vector> |
12 | 15 |
13 #include "base/files/file_path.h" | 16 #include "base/files/file_path.h" |
14 #include "base/logging.h" | 17 #include "base/logging.h" |
15 #include "base/macros.h" | 18 #include "base/macros.h" |
16 #include "base/memory/scoped_ptr.h" | 19 #include "base/memory/scoped_ptr.h" |
17 #include "base/metrics/histogram_samples.h" | 20 #include "base/metrics/histogram_samples.h" |
18 #include "base/run_loop.h" | 21 #include "base/run_loop.h" |
19 #include "base/strings/string_number_conversions.h" | 22 #include "base/strings/string_number_conversions.h" |
20 #include "base/test/histogram_tester.h" | 23 #include "base/test/histogram_tester.h" |
21 #include "base/time/time.h" | 24 #include "base/time/time.h" |
22 #include "build/build_config.h" | 25 #include "build/build_config.h" |
23 #include "net/base/external_estimate_provider.h" | 26 #include "net/base/external_estimate_provider.h" |
24 #include "net/base/load_flags.h" | 27 #include "net/base/load_flags.h" |
25 #include "net/base/network_change_notifier.h" | 28 #include "net/base/network_change_notifier.h" |
| 29 #include "net/base/socket_performance_watcher_factory.h" |
26 #include "net/http/http_status_code.h" | 30 #include "net/http/http_status_code.h" |
27 #include "net/test/embedded_test_server/embedded_test_server.h" | 31 #include "net/test/embedded_test_server/embedded_test_server.h" |
28 #include "net/test/embedded_test_server/http_request.h" | 32 #include "net/test/embedded_test_server/http_request.h" |
29 #include "net/test/embedded_test_server/http_response.h" | 33 #include "net/test/embedded_test_server/http_response.h" |
30 #include "net/url_request/url_request_test_util.h" | 34 #include "net/url_request/url_request_test_util.h" |
31 #include "testing/gtest/include/gtest/gtest.h" | 35 #include "testing/gtest/include/gtest/gtest.h" |
32 #include "url/gurl.h" | 36 #include "url/gurl.h" |
33 | 37 |
34 namespace { | 38 namespace { |
35 | 39 |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
150 int32_t throughput_kbps, | 154 int32_t throughput_kbps, |
151 const base::TimeTicks& timestamp, | 155 const base::TimeTicks& timestamp, |
152 net::NetworkQualityEstimator::ObservationSource source) override { | 156 net::NetworkQualityEstimator::ObservationSource source) override { |
153 observations_.push_back(Observation(throughput_kbps, timestamp, source)); | 157 observations_.push_back(Observation(throughput_kbps, timestamp, source)); |
154 } | 158 } |
155 | 159 |
156 private: | 160 private: |
157 std::vector<Observation> observations_; | 161 std::vector<Observation> observations_; |
158 }; | 162 }; |
159 | 163 |
| 164 class TestPacketLossObserver |
| 165 : public net::NetworkQualityEstimator::PacketLossObserver { |
| 166 public: |
| 167 struct Observation { |
| 168 Observation(size_t packets_lost, |
| 169 size_t packets_received_in_order, |
| 170 size_t packets_received_out_of_order, |
| 171 const base::TimeTicks& ts, |
| 172 net::NetworkQualityEstimator::ObservationSource src) |
| 173 : packets_lost(packets_lost), |
| 174 packets_received_in_order(packets_received_in_order), |
| 175 packets_received_out_of_order(packets_received_out_of_order), |
| 176 timestamp(ts), |
| 177 source(src) {} |
| 178 size_t packets_lost; |
| 179 size_t packets_received_in_order; |
| 180 size_t packets_received_out_of_order; |
| 181 base::TimeTicks timestamp; |
| 182 net::NetworkQualityEstimator::ObservationSource source; |
| 183 }; |
| 184 |
| 185 std::vector<Observation>& observations() { return observations_; } |
| 186 |
| 187 // PacketLossObserver implementation: |
| 188 void OnPacketLossObservation( |
| 189 size_t packets_lost, |
| 190 size_t packets_received_in_order, |
| 191 size_t packets_received_out_of_order, |
| 192 const base::TimeTicks& timestamp, |
| 193 net::NetworkQualityEstimator::ObservationSource source) override { |
| 194 observations_.push_back(Observation(packets_lost, packets_received_in_order, |
| 195 packets_received_out_of_order, |
| 196 timestamp, source)); |
| 197 } |
| 198 |
| 199 private: |
| 200 std::vector<Observation> observations_; |
| 201 }; |
| 202 |
160 } // namespace | 203 } // namespace |
161 | 204 |
162 namespace net { | 205 namespace net { |
163 | 206 |
164 TEST(NetworkQualityEstimatorTest, TestKbpsRTTUpdates) { | 207 TEST(NetworkQualityEstimatorTest, TestKbpsRTTUpdates) { |
165 base::HistogramTester histogram_tester; | 208 base::HistogramTester histogram_tester; |
166 // Enable requests to local host to be used for network quality estimation. | 209 // Enable requests to local host to be used for network quality estimation. |
167 std::map<std::string, std::string> variation_params; | 210 std::map<std::string, std::string> variation_params; |
168 TestNetworkQualityEstimator estimator(variation_params); | 211 TestNetworkQualityEstimator estimator(variation_params); |
169 | 212 |
(...skipping 78 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
248 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(), | 291 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(), |
249 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); | 292 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); |
250 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput, | 293 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput, |
251 estimator.GetDownlinkThroughputKbpsEstimateInternal( | 294 estimator.GetDownlinkThroughputKbpsEstimateInternal( |
252 base::TimeTicks(), 100)); | 295 base::TimeTicks(), 100)); |
253 | 296 |
254 EXPECT_FALSE(estimator.GetRTTEstimate(&rtt)); | 297 EXPECT_FALSE(estimator.GetRTTEstimate(&rtt)); |
255 EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); | 298 EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); |
256 } | 299 } |
257 | 300 |
| 301 // Tests that packet loss rate is updated correctly. |
| 302 TEST(NetworkQualityEstimatorTest, TestPacketLossRateUpdates) { |
| 303 std::map<std::string, std::string> variation_params; |
| 304 TestNetworkQualityEstimator estimator(variation_params); |
| 305 |
| 306 float packet_loss_rate; |
| 307 EXPECT_FALSE(estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
| 308 |
| 309 estimator.OnUpdatedPacketCountAvailable( |
| 310 NetworkQualityEstimator::PROTOCOL_QUIC, 0, 1, 1); |
| 311 |
| 312 EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
| 313 EXPECT_NEAR(0.0f, packet_loss_rate, 0.001f); |
| 314 |
| 315 estimator.SimulateNetworkChangeTo( |
| 316 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, std::string()); |
| 317 |
| 318 EXPECT_FALSE(estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
| 319 |
| 320 // Expecting packet number i, but received packet number i+9. 1 out of 10 |
| 321 // packets have been received. |
| 322 estimator.OnUpdatedPacketCountAvailable( |
| 323 NetworkQualityEstimator::PROTOCOL_QUIC, 9, 1, 0); |
| 324 EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
| 325 EXPECT_NEAR(9.0f / 10, packet_loss_rate, 0.001f); |
| 326 |
| 327 // Expecting packet number i+10, and received packet number i+10. 2 out |
| 328 // of 11 packets have been received. |
| 329 estimator.OnUpdatedPacketCountAvailable( |
| 330 NetworkQualityEstimator::PROTOCOL_QUIC, 0, 1, 0); |
| 331 EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
| 332 EXPECT_NEAR(9.0f / 11, packet_loss_rate, 0.001f); |
| 333 |
| 334 // Expecting packet number i+11, and received packet number i+11. 3 out |
| 335 // of 12 packets have been received. |
| 336 estimator.OnUpdatedPacketCountAvailable( |
| 337 NetworkQualityEstimator::PROTOCOL_QUIC, 0, 1, 0); |
| 338 EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
| 339 EXPECT_NEAR(9.0f / 12, packet_loss_rate, 0.001f); |
| 340 |
| 341 // Expecting packet number i+12, but received packet number i. 3 out of |
| 342 // 12 packets have been received. |
| 343 estimator.OnUpdatedPacketCountAvailable( |
| 344 NetworkQualityEstimator::PROTOCOL_QUIC, 0, 0, 1); |
| 345 EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
| 346 EXPECT_NEAR(9.0f / 12, packet_loss_rate, 0.001f); |
| 347 } |
| 348 |
| 349 // Tests that packet loss UMA histogram is recorded properly. |
| 350 TEST(NetworkQualityEstimatorTest, TestPacketLossRateHistogram) { |
| 351 std::map<std::string, std::string> variation_params; |
| 352 TestNetworkQualityEstimator estimator(variation_params); |
| 353 |
| 354 TestDelegate test_delegate; |
| 355 TestURLRequestContext context(true); |
| 356 context.set_network_quality_estimator(&estimator); |
| 357 context.Init(); |
| 358 |
| 359 const struct { |
| 360 bool notify_packet_counts; |
| 361 bool set_mainframe_flag; |
| 362 } tests[] = { |
| 363 { |
| 364 false, false, |
| 365 }, |
| 366 { |
| 367 false, true, |
| 368 }, |
| 369 { |
| 370 true, false, |
| 371 }, |
| 372 { |
| 373 true, true, |
| 374 }, |
| 375 }; |
| 376 |
| 377 for (auto test : tests) { |
| 378 base::HistogramTester histogram_tester; |
| 379 estimator.SimulateNetworkChangeTo( |
| 380 NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test"); |
| 381 |
| 382 float packet_loss_rate; |
| 383 EXPECT_FALSE(estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
| 384 |
| 385 if (test.notify_packet_counts) { |
| 386 estimator.OnUpdatedPacketCountAvailable( |
| 387 NetworkQualityEstimator::PROTOCOL_QUIC, 0, 1, 1); |
| 388 } |
| 389 EXPECT_EQ(test.notify_packet_counts, |
| 390 estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
| 391 |
| 392 for (size_t i = 0; i < 2; ++i) { |
| 393 // Check UMA histograms. |
| 394 scoped_ptr<URLRequest> request(context.CreateRequest( |
| 395 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); |
| 396 if (test.set_mainframe_flag) { |
| 397 request->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME); |
| 398 } |
| 399 request->Start(); |
| 400 base::RunLoop().Run(); |
| 401 size_t expect_histogram_count = |
| 402 test.notify_packet_counts && test.set_mainframe_flag ? i + 1 : 0; |
| 403 histogram_tester.ExpectTotalCount("NQE.PacketLossRate.WiFi", |
| 404 expect_histogram_count); |
| 405 } |
| 406 } |
| 407 } |
| 408 |
258 TEST(NetworkQualityEstimatorTest, StoreObservations) { | 409 TEST(NetworkQualityEstimatorTest, StoreObservations) { |
259 std::map<std::string, std::string> variation_params; | 410 std::map<std::string, std::string> variation_params; |
260 TestNetworkQualityEstimator estimator(variation_params); | 411 TestNetworkQualityEstimator estimator(variation_params); |
261 | 412 |
262 TestDelegate test_delegate; | 413 TestDelegate test_delegate; |
263 TestURLRequestContext context(true); | 414 TestURLRequestContext context(true); |
264 context.set_network_quality_estimator(&estimator); | 415 context.set_network_quality_estimator(&estimator); |
265 context.Init(); | 416 context.Init(); |
266 | 417 |
267 // Push 10 more observations than the maximum buffer size. | 418 // Push 10 more observations than the maximum buffer size. |
(...skipping 24 matching lines...) Expand all Loading... |
292 TEST(NetworkQualityEstimatorTest, PercentileSameTimestamps) { | 443 TEST(NetworkQualityEstimatorTest, PercentileSameTimestamps) { |
293 std::map<std::string, std::string> variation_params; | 444 std::map<std::string, std::string> variation_params; |
294 TestNetworkQualityEstimator estimator(variation_params); | 445 TestNetworkQualityEstimator estimator(variation_params); |
295 base::TimeTicks now = base::TimeTicks::Now(); | 446 base::TimeTicks now = base::TimeTicks::Now(); |
296 | 447 |
297 // Network quality should be unavailable when no observations are available. | 448 // Network quality should be unavailable when no observations are available. |
298 base::TimeDelta rtt; | 449 base::TimeDelta rtt; |
299 EXPECT_FALSE(estimator.GetRTTEstimate(&rtt)); | 450 EXPECT_FALSE(estimator.GetRTTEstimate(&rtt)); |
300 int32_t kbps; | 451 int32_t kbps; |
301 EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); | 452 EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); |
| 453 float packet_loss_rate; |
| 454 EXPECT_FALSE(estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
302 | 455 |
303 // Insert samples from {1,2,3,..., 100}. First insert odd samples, then even | 456 // Insert samples from {1,2,3,..., 100}. First insert odd samples, then even |
304 // samples. This helps in verifying that the order of samples does not matter. | 457 // samples. This helps in verifying that the order of samples does not matter. |
305 for (int i = 1; i <= 99; i += 2) { | 458 for (int i = 1; i <= 99; i += 2) { |
306 estimator.downstream_throughput_kbps_observations_.AddObservation( | 459 estimator.downstream_throughput_kbps_observations_.AddObservation( |
307 NetworkQualityEstimator::ThroughputObservation( | 460 NetworkQualityEstimator::ThroughputObservation( |
308 i, now, NetworkQualityEstimator::URL_REQUEST)); | 461 i, now, NetworkQualityEstimator::URL_REQUEST)); |
309 estimator.rtt_msec_observations_.AddObservation( | 462 estimator.rtt_msec_observations_.AddObservation( |
310 NetworkQualityEstimator::RttObservation( | 463 NetworkQualityEstimator::RttObservation( |
311 base::TimeDelta::FromMilliseconds(i), now, | 464 base::TimeDelta::FromMilliseconds(i), now, |
312 NetworkQualityEstimator::URL_REQUEST)); | 465 NetworkQualityEstimator::URL_REQUEST)); |
| 466 estimator.packet_loss_rate_observations_.AddObservation( |
| 467 NetworkQualityEstimator::PacketLossRateObservation( |
| 468 0.0f, now, NetworkQualityEstimator::QUIC)); |
313 EXPECT_TRUE(estimator.GetRTTEstimate(&rtt)); | 469 EXPECT_TRUE(estimator.GetRTTEstimate(&rtt)); |
314 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); | 470 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); |
| 471 EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
315 } | 472 } |
316 | 473 |
317 for (int i = 2; i <= 100; i += 2) { | 474 for (int i = 2; i <= 100; i += 2) { |
318 estimator.downstream_throughput_kbps_observations_.AddObservation( | 475 estimator.downstream_throughput_kbps_observations_.AddObservation( |
319 NetworkQualityEstimator::ThroughputObservation( | 476 NetworkQualityEstimator::ThroughputObservation( |
320 i, now, NetworkQualityEstimator::URL_REQUEST)); | 477 i, now, NetworkQualityEstimator::URL_REQUEST)); |
321 estimator.rtt_msec_observations_.AddObservation( | 478 estimator.rtt_msec_observations_.AddObservation( |
322 NetworkQualityEstimator::RttObservation( | 479 NetworkQualityEstimator::RttObservation( |
323 base::TimeDelta::FromMilliseconds(i), now, | 480 base::TimeDelta::FromMilliseconds(i), now, |
324 NetworkQualityEstimator::URL_REQUEST)); | 481 NetworkQualityEstimator::URL_REQUEST)); |
| 482 estimator.packet_loss_rate_observations_.AddObservation( |
| 483 NetworkQualityEstimator::PacketLossRateObservation( |
| 484 1.0, now, NetworkQualityEstimator::QUIC)); |
325 EXPECT_TRUE(estimator.GetRTTEstimate(&rtt)); | 485 EXPECT_TRUE(estimator.GetRTTEstimate(&rtt)); |
326 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); | 486 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); |
| 487 EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
327 } | 488 } |
328 | 489 |
329 for (int i = 0; i <= 100; ++i) { | 490 for (int i = 0; i <= 100; ++i) { |
330 // Checks if the difference between the two integers is less than 1. This is | 491 // Checks if the difference between the two integers is less than 1. This is |
331 // required because computed percentiles may be slightly different from | 492 // required because computed percentiles may be slightly different from |
332 // what is expected due to floating point computation errors and integer | 493 // what is expected due to floating point computation errors and integer |
333 // rounding off errors. | 494 // rounding off errors. |
334 EXPECT_NEAR(estimator.GetDownlinkThroughputKbpsEstimateInternal( | 495 EXPECT_NEAR(estimator.GetDownlinkThroughputKbpsEstimateInternal( |
335 base::TimeTicks(), i), | 496 base::TimeTicks(), i), |
336 100 - i, 1); | 497 100 - i, 1); |
337 EXPECT_NEAR( | 498 EXPECT_NEAR( |
338 estimator.GetRTTEstimateInternal(base::TimeTicks(), i).InMilliseconds(), | 499 estimator.GetRTTEstimateInternal(base::TimeTicks(), i).InMilliseconds(), |
339 i, 1); | 500 i, 1); |
340 } | 501 } |
341 | 502 |
342 EXPECT_TRUE(estimator.GetRTTEstimate(&rtt)); | 503 EXPECT_TRUE(estimator.GetRTTEstimate(&rtt)); |
343 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); | 504 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); |
344 // |network_quality| should be equal to the 50 percentile value. | 505 // |network_quality| should be equal to the 50 percentile value. |
345 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimateInternal( | 506 EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimateInternal( |
346 base::TimeTicks(), 50) > 0); | 507 base::TimeTicks(), 50) > 0); |
347 EXPECT_TRUE(estimator.GetRTTEstimateInternal(base::TimeTicks(), 50) != | 508 EXPECT_TRUE(estimator.GetRTTEstimateInternal(base::TimeTicks(), 50) != |
348 NetworkQualityEstimator::InvalidRTT()); | 509 NetworkQualityEstimator::InvalidRTT()); |
| 510 EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
| 511 EXPECT_NEAR(0.5f, packet_loss_rate, 0.001f); |
349 } | 512 } |
350 | 513 |
351 // Verifies that the percentiles are correctly computed. Observations have | 514 // Verifies that the percentiles are correctly computed. Observations have |
352 // different timestamps with half the observations being very old and the rest | 515 // different timestamps with half the observations being very old and the rest |
353 // of them being very recent. Percentiles should factor in recent observations | 516 // of them being very recent. Percentiles should factor in recent observations |
354 // much more heavily than older samples. Kbps percentiles must be in decreasing | 517 // much more heavily than older samples. Kbps percentiles must be in decreasing |
355 // order. RTT percentiles must be in increasing order. | 518 // order. RTT percentiles must be in increasing order. |
356 TEST(NetworkQualityEstimatorTest, PercentileDifferentTimestamps) { | 519 TEST(NetworkQualityEstimatorTest, PercentileDifferentTimestamps) { |
357 std::map<std::string, std::string> variation_params; | 520 std::map<std::string, std::string> variation_params; |
358 TestNetworkQualityEstimator estimator(variation_params); | 521 TestNetworkQualityEstimator estimator(variation_params); |
359 base::TimeTicks now = base::TimeTicks::Now(); | 522 base::TimeTicks now = base::TimeTicks::Now(); |
360 base::TimeTicks very_old = base::TimeTicks::UnixEpoch(); | 523 base::TimeTicks very_old = base::TimeTicks::UnixEpoch(); |
361 | 524 |
| 525 float packet_loss_rate; |
| 526 EXPECT_FALSE(estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
| 527 |
362 // First 50 samples have very old timestamp. | 528 // First 50 samples have very old timestamp. |
363 for (int i = 1; i <= 50; ++i) { | 529 for (int i = 1; i <= 50; ++i) { |
364 estimator.downstream_throughput_kbps_observations_.AddObservation( | 530 estimator.downstream_throughput_kbps_observations_.AddObservation( |
365 NetworkQualityEstimator::ThroughputObservation( | 531 NetworkQualityEstimator::ThroughputObservation( |
366 i, very_old, NetworkQualityEstimator::URL_REQUEST)); | 532 i, very_old, NetworkQualityEstimator::URL_REQUEST)); |
367 estimator.rtt_msec_observations_.AddObservation( | 533 estimator.rtt_msec_observations_.AddObservation( |
368 NetworkQualityEstimator::RttObservation( | 534 NetworkQualityEstimator::RttObservation( |
369 base::TimeDelta::FromMilliseconds(i), very_old, | 535 base::TimeDelta::FromMilliseconds(i), very_old, |
370 NetworkQualityEstimator::URL_REQUEST)); | 536 NetworkQualityEstimator::URL_REQUEST)); |
| 537 estimator.packet_loss_rate_observations_.AddObservation( |
| 538 NetworkQualityEstimator::PacketLossRateObservation( |
| 539 0.0f, very_old, NetworkQualityEstimator::QUIC)); |
371 } | 540 } |
372 | 541 |
373 // Next 50 (i.e., from 51 to 100) have recent timestamp. | 542 // Next 50 (i.e., from 51 to 100) have recent timestamp. |
374 for (int i = 51; i <= 100; ++i) { | 543 for (int i = 51; i <= 100; ++i) { |
375 estimator.downstream_throughput_kbps_observations_.AddObservation( | 544 estimator.downstream_throughput_kbps_observations_.AddObservation( |
376 NetworkQualityEstimator::ThroughputObservation( | 545 NetworkQualityEstimator::ThroughputObservation( |
377 i, now, NetworkQualityEstimator::URL_REQUEST)); | 546 i, now, NetworkQualityEstimator::URL_REQUEST)); |
378 estimator.rtt_msec_observations_.AddObservation( | 547 estimator.rtt_msec_observations_.AddObservation( |
379 NetworkQualityEstimator::RttObservation( | 548 NetworkQualityEstimator::RttObservation( |
380 base::TimeDelta::FromMilliseconds(i), now, | 549 base::TimeDelta::FromMilliseconds(i), now, |
381 NetworkQualityEstimator::URL_REQUEST)); | 550 NetworkQualityEstimator::URL_REQUEST)); |
| 551 estimator.packet_loss_rate_observations_.AddObservation( |
| 552 NetworkQualityEstimator::PacketLossRateObservation( |
| 553 1.0, now, NetworkQualityEstimator::QUIC)); |
382 } | 554 } |
383 | 555 |
384 // Older samples have very little weight. So, all percentiles are >= 51 | 556 // Older samples have very little weight. So, all percentiles are >= 51 |
385 // (lowest value among recent observations). | 557 // (lowest value among recent observations). |
386 for (int i = 1; i < 100; ++i) { | 558 for (int i = 1; i < 100; ++i) { |
387 // Checks if the difference between the two integers is less than 1. This is | 559 // Checks if the difference between the two integers is less than 1. This is |
388 // required because computed percentiles may be slightly different from | 560 // required because computed percentiles may be slightly different from |
389 // what is expected due to floating point computation errors and integer | 561 // what is expected due to floating point computation errors and integer |
390 // rounding off errors. | 562 // rounding off errors. |
391 EXPECT_NEAR(estimator.GetDownlinkThroughputKbpsEstimateInternal( | 563 EXPECT_NEAR(estimator.GetDownlinkThroughputKbpsEstimateInternal( |
392 base::TimeTicks(), i), | 564 base::TimeTicks(), i), |
393 51 + 0.49 * (100 - i), 1); | 565 51 + 0.49 * (100 - i), 1); |
394 EXPECT_NEAR( | 566 EXPECT_NEAR( |
395 estimator.GetRTTEstimateInternal(base::TimeTicks(), i).InMilliseconds(), | 567 estimator.GetRTTEstimateInternal(base::TimeTicks(), i).InMilliseconds(), |
396 51 + 0.49 * i, 1); | 568 51 + 0.49 * i, 1); |
397 } | 569 } |
398 | 570 |
399 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(), | 571 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(), |
400 estimator.GetRTTEstimateInternal( | 572 estimator.GetRTTEstimateInternal( |
401 base::TimeTicks::Now() + base::TimeDelta::FromMinutes(10), 50)); | 573 base::TimeTicks::Now() + base::TimeDelta::FromMinutes(10), 50)); |
402 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput, | 574 EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput, |
403 estimator.GetDownlinkThroughputKbpsEstimateInternal( | 575 estimator.GetDownlinkThroughputKbpsEstimateInternal( |
404 base::TimeTicks::Now() + base::TimeDelta::FromMinutes(10), 50)); | 576 base::TimeTicks::Now() + base::TimeDelta::FromMinutes(10), 50)); |
| 577 |
| 578 EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
| 579 EXPECT_NEAR(1.0, packet_loss_rate, 0.001f); |
405 } | 580 } |
406 | 581 |
407 // This test notifies NetworkQualityEstimator of received data. Next, | 582 // This test notifies NetworkQualityEstimator of received data. Next, |
408 // throughput and RTT percentiles are checked for correctness by doing simple | 583 // throughput and RTT percentiles are checked for correctness by doing simple |
409 // verifications. | 584 // verifications. |
410 TEST(NetworkQualityEstimatorTest, ComputedPercentiles) { | 585 TEST(NetworkQualityEstimatorTest, ComputedPercentiles) { |
411 std::map<std::string, std::string> variation_params; | 586 std::map<std::string, std::string> variation_params; |
412 TestNetworkQualityEstimator estimator(variation_params); | 587 TestNetworkQualityEstimator estimator(variation_params); |
413 | 588 |
414 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(), | 589 EXPECT_EQ(NetworkQualityEstimator::InvalidRTT(), |
(...skipping 114 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 } | 704 } |
530 | 705 |
531 TEST(NetworkQualityEstimatorTest, HalfLifeParam) { | 706 TEST(NetworkQualityEstimatorTest, HalfLifeParam) { |
532 // Verifies if |weight_multiplier_per_second_| is set to correct value for | 707 // Verifies if |weight_multiplier_per_second_| is set to correct value for |
533 // various values of half life parameter. | 708 // various values of half life parameter. |
534 std::map<std::string, std::string> variation_params; | 709 std::map<std::string, std::string> variation_params; |
535 { | 710 { |
536 // Half life parameter is not set. Default value of | 711 // Half life parameter is not set. Default value of |
537 // |weight_multiplier_per_second_| should be used. | 712 // |weight_multiplier_per_second_| should be used. |
538 TestNetworkQualityEstimator estimator(variation_params); | 713 TestNetworkQualityEstimator estimator(variation_params); |
539 EXPECT_NEAR(0.988, estimator.downstream_throughput_kbps_observations_ | 714 EXPECT_NEAR(0.988f, estimator.downstream_throughput_kbps_observations_ |
540 .weight_multiplier_per_second_, | 715 .weight_multiplier_per_second_, |
541 0.001); | 716 0.001f); |
542 } | 717 } |
543 | 718 |
544 variation_params["HalfLifeSeconds"] = "-100"; | 719 variation_params["HalfLifeSeconds"] = "-100"; |
545 { | 720 { |
546 // Half life parameter is set to a negative value. Default value of | 721 // Half life parameter is set to a negative value. Default value of |
547 // |weight_multiplier_per_second_| should be used. | 722 // |weight_multiplier_per_second_| should be used. |
548 TestNetworkQualityEstimator estimator(variation_params); | 723 TestNetworkQualityEstimator estimator(variation_params); |
549 EXPECT_NEAR(0.988, estimator.downstream_throughput_kbps_observations_ | 724 EXPECT_NEAR(0.988f, estimator.downstream_throughput_kbps_observations_ |
550 .weight_multiplier_per_second_, | 725 .weight_multiplier_per_second_, |
551 0.001); | 726 0.001f); |
552 } | 727 } |
553 | 728 |
554 variation_params["HalfLifeSeconds"] = "0"; | 729 variation_params["HalfLifeSeconds"] = "0"; |
555 { | 730 { |
556 // Half life parameter is set to zero. Default value of | 731 // Half life parameter is set to zero. Default value of |
557 // |weight_multiplier_per_second_| should be used. | 732 // |weight_multiplier_per_second_| should be used. |
558 TestNetworkQualityEstimator estimator(variation_params); | 733 TestNetworkQualityEstimator estimator(variation_params); |
559 EXPECT_NEAR(0.988, estimator.downstream_throughput_kbps_observations_ | 734 EXPECT_NEAR(0.988f, estimator.downstream_throughput_kbps_observations_ |
560 .weight_multiplier_per_second_, | 735 .weight_multiplier_per_second_, |
561 0.001); | 736 0.001f); |
562 } | 737 } |
563 | 738 |
564 variation_params["HalfLifeSeconds"] = "10"; | 739 variation_params["HalfLifeSeconds"] = "10"; |
565 { | 740 { |
566 // Half life parameter is set to a valid value. | 741 // Half life parameter is set to a valid value. |
567 TestNetworkQualityEstimator estimator(variation_params); | 742 TestNetworkQualityEstimator estimator(variation_params); |
568 EXPECT_NEAR(0.933, estimator.downstream_throughput_kbps_observations_ | 743 EXPECT_NEAR(0.933f, estimator.downstream_throughput_kbps_observations_ |
569 .weight_multiplier_per_second_, | 744 .weight_multiplier_per_second_, |
570 0.001); | 745 0.001f); |
571 } | 746 } |
572 } | 747 } |
573 | 748 |
574 // Test if the network estimates are cached when network change notification | 749 // Test if the network estimates are cached when network change notification |
575 // is invoked. | 750 // is invoked. |
576 TEST(NetworkQualityEstimatorTest, TestCaching) { | 751 TEST(NetworkQualityEstimatorTest, TestCaching) { |
577 std::map<std::string, std::string> variation_params; | 752 std::map<std::string, std::string> variation_params; |
578 TestNetworkQualityEstimator estimator(variation_params); | 753 TestNetworkQualityEstimator estimator(variation_params); |
579 size_t expected_cache_size = 0; | 754 size_t expected_cache_size = 0; |
580 EXPECT_EQ(expected_cache_size, estimator.cached_network_qualities_.size()); | 755 EXPECT_EQ(expected_cache_size, estimator.cached_network_qualities_.size()); |
(...skipping 438 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
1019 request->Start(); | 1194 request->Start(); |
1020 base::RunLoop().Run(); | 1195 base::RunLoop().Run(); |
1021 | 1196 |
1022 EXPECT_EQ(2U, estimator.rtt_msec_observations_.Size()); | 1197 EXPECT_EQ(2U, estimator.rtt_msec_observations_.Size()); |
1023 EXPECT_EQ(2U, estimator.downstream_throughput_kbps_observations_.Size()); | 1198 EXPECT_EQ(2U, estimator.downstream_throughput_kbps_observations_.Size()); |
1024 } | 1199 } |
1025 | 1200 |
1026 TEST(NetworkQualityEstimatorTest, TestObservers) { | 1201 TEST(NetworkQualityEstimatorTest, TestObservers) { |
1027 TestRTTObserver rtt_observer; | 1202 TestRTTObserver rtt_observer; |
1028 TestThroughputObserver throughput_observer; | 1203 TestThroughputObserver throughput_observer; |
| 1204 TestPacketLossObserver packet_loss_observer; |
1029 std::map<std::string, std::string> variation_params; | 1205 std::map<std::string, std::string> variation_params; |
1030 TestNetworkQualityEstimator estimator(variation_params); | 1206 TestNetworkQualityEstimator estimator(variation_params); |
1031 estimator.AddRTTObserver(&rtt_observer); | 1207 estimator.AddRTTObserver(&rtt_observer); |
1032 estimator.AddThroughputObserver(&throughput_observer); | 1208 estimator.AddThroughputObserver(&throughput_observer); |
| 1209 estimator.AddPacketLossObserver(&packet_loss_observer); |
1033 | 1210 |
1034 TestDelegate test_delegate; | 1211 TestDelegate test_delegate; |
1035 TestURLRequestContext context(true); | 1212 TestURLRequestContext context(true); |
1036 context.set_network_quality_estimator(&estimator); | 1213 context.set_network_quality_estimator(&estimator); |
1037 context.Init(); | 1214 context.Init(); |
1038 | 1215 |
1039 EXPECT_EQ(0U, rtt_observer.observations().size()); | 1216 EXPECT_EQ(0U, rtt_observer.observations().size()); |
1040 EXPECT_EQ(0U, throughput_observer.observations().size()); | 1217 EXPECT_EQ(0U, throughput_observer.observations().size()); |
1041 base::TimeTicks then = base::TimeTicks::Now(); | 1218 base::TimeTicks then = base::TimeTicks::Now(); |
1042 | 1219 |
1043 scoped_ptr<URLRequest> request(context.CreateRequest( | 1220 scoped_ptr<URLRequest> request(context.CreateRequest( |
1044 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); | 1221 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); |
1045 request->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME); | 1222 request->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME); |
1046 request->Start(); | 1223 request->Start(); |
1047 base::RunLoop().Run(); | 1224 base::RunLoop().Run(); |
1048 | 1225 |
1049 scoped_ptr<URLRequest> request2(context.CreateRequest( | 1226 scoped_ptr<URLRequest> request2(context.CreateRequest( |
1050 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); | 1227 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); |
1051 request2->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME); | 1228 request2->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME); |
1052 request2->Start(); | 1229 request2->Start(); |
1053 base::RunLoop().Run(); | 1230 base::RunLoop().Run(); |
1054 | 1231 |
| 1232 float packet_loss_rate; |
| 1233 EXPECT_FALSE(estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
| 1234 |
| 1235 estimator.OnUpdatedPacketCountAvailable( |
| 1236 NetworkQualityEstimator::PROTOCOL_QUIC, 0, 1, 1); |
| 1237 EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
| 1238 EXPECT_NEAR(0.0f, packet_loss_rate, 0.001f); |
| 1239 |
1055 // Both RTT and downstream throughput should be updated. | 1240 // Both RTT and downstream throughput should be updated. |
1056 EXPECT_NE(NetworkQualityEstimator::InvalidRTT(), | 1241 EXPECT_NE(NetworkQualityEstimator::InvalidRTT(), |
1057 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); | 1242 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); |
1058 EXPECT_NE(NetworkQualityEstimator::kInvalidThroughput, | 1243 EXPECT_NE(NetworkQualityEstimator::kInvalidThroughput, |
1059 estimator.GetDownlinkThroughputKbpsEstimateInternal( | 1244 estimator.GetDownlinkThroughputKbpsEstimateInternal( |
1060 base::TimeTicks(), 100)); | 1245 base::TimeTicks(), 100)); |
1061 | 1246 |
1062 EXPECT_EQ(2U, rtt_observer.observations().size()); | 1247 EXPECT_EQ(2U, rtt_observer.observations().size()); |
1063 EXPECT_EQ(2U, throughput_observer.observations().size()); | 1248 EXPECT_EQ(2U, throughput_observer.observations().size()); |
| 1249 ASSERT_EQ(1U, packet_loss_observer.observations().size()); |
1064 for (auto observation : rtt_observer.observations()) { | 1250 for (auto observation : rtt_observer.observations()) { |
1065 EXPECT_LE(0, observation.rtt_ms); | 1251 EXPECT_LE(0, observation.rtt_ms); |
1066 EXPECT_LE(0, (observation.timestamp - then).InMilliseconds()); | 1252 EXPECT_LE(0, (observation.timestamp - then).InMilliseconds()); |
1067 EXPECT_EQ(NetworkQualityEstimator::URL_REQUEST, observation.source); | 1253 EXPECT_EQ(NetworkQualityEstimator::URL_REQUEST, observation.source); |
1068 } | 1254 } |
1069 for (auto observation : throughput_observer.observations()) { | 1255 for (auto observation : throughput_observer.observations()) { |
1070 EXPECT_LE(0, observation.throughput_kbps); | 1256 EXPECT_LE(0, observation.throughput_kbps); |
1071 EXPECT_LE(0, (observation.timestamp - then).InMilliseconds()); | 1257 EXPECT_LE(0, (observation.timestamp - then).InMilliseconds()); |
1072 EXPECT_EQ(NetworkQualityEstimator::URL_REQUEST, observation.source); | 1258 EXPECT_EQ(NetworkQualityEstimator::URL_REQUEST, observation.source); |
1073 } | 1259 } |
| 1260 for (auto observation : packet_loss_observer.observations()) { |
| 1261 EXPECT_LE(0u, observation.packets_lost); |
| 1262 EXPECT_LE(1u, observation.packets_received_in_order); |
| 1263 EXPECT_LE(0u, observation.packets_received_out_of_order); |
| 1264 EXPECT_LE(0, (observation.timestamp - then).InMilliseconds()); |
| 1265 EXPECT_EQ(NetworkQualityEstimator::QUIC, observation.source); |
| 1266 } |
1074 | 1267 |
1075 // Verify that observations from TCP and QUIC are passed on to the observers. | 1268 // Verify that observations from TCP and QUIC are passed on to the observers. |
1076 base::TimeDelta tcp_rtt(base::TimeDelta::FromMilliseconds(1)); | 1269 base::TimeDelta tcp_rtt(base::TimeDelta::FromMilliseconds(1)); |
1077 base::TimeDelta quic_rtt(base::TimeDelta::FromMilliseconds(2)); | 1270 base::TimeDelta quic_rtt(base::TimeDelta::FromMilliseconds(2)); |
1078 | 1271 |
1079 scoped_ptr<SocketPerformanceWatcher> tcp_watcher = | 1272 scoped_ptr<SocketPerformanceWatcher> tcp_watcher = |
1080 estimator.CreateSocketPerformanceWatcher( | 1273 estimator.CreateSocketPerformanceWatcher( |
1081 SocketPerformanceWatcherFactory::PROTOCOL_TCP); | 1274 SocketPerformanceWatcherFactory::PROTOCOL_TCP); |
1082 scoped_ptr<SocketPerformanceWatcher> quic_watcher = | 1275 scoped_ptr<SocketPerformanceWatcher> quic_watcher = |
1083 estimator.CreateSocketPerformanceWatcher( | 1276 estimator.CreateSocketPerformanceWatcher( |
1084 SocketPerformanceWatcherFactory::PROTOCOL_QUIC); | 1277 SocketPerformanceWatcherFactory::PROTOCOL_QUIC); |
1085 tcp_watcher->OnUpdatedRTTAvailable(tcp_rtt); | 1278 tcp_watcher->OnUpdatedRTTAvailable(tcp_rtt); |
1086 quic_watcher->OnUpdatedRTTAvailable(quic_rtt); | 1279 quic_watcher->OnUpdatedRTTAvailable(quic_rtt); |
1087 | 1280 |
1088 EXPECT_EQ(4U, rtt_observer.observations().size()); | 1281 EXPECT_EQ(4U, rtt_observer.observations().size()); |
1089 EXPECT_EQ(2U, throughput_observer.observations().size()); | 1282 EXPECT_EQ(2U, throughput_observer.observations().size()); |
1090 | 1283 |
1091 EXPECT_EQ(tcp_rtt.InMilliseconds(), rtt_observer.observations().at(2).rtt_ms); | 1284 EXPECT_EQ(tcp_rtt.InMilliseconds(), rtt_observer.observations().at(2).rtt_ms); |
1092 EXPECT_EQ(quic_rtt.InMilliseconds(), | 1285 EXPECT_EQ(quic_rtt.InMilliseconds(), |
1093 rtt_observer.observations().at(3).rtt_ms); | 1286 rtt_observer.observations().at(3).rtt_ms); |
1094 } | 1287 } |
1095 | 1288 |
1096 } // namespace net | 1289 } // namespace net |
OLD | NEW |