| Index: net/base/network_quality_estimator_unittest.cc
|
| diff --git a/net/base/network_quality_estimator_unittest.cc b/net/base/network_quality_estimator_unittest.cc
|
| index 25e386db44db573184f628053115c75be6ea87e5..8b0003f5862d77dc459c0ce3c0694137685a4408 100644
|
| --- a/net/base/network_quality_estimator_unittest.cc
|
| +++ b/net/base/network_quality_estimator_unittest.cc
|
| @@ -23,6 +23,7 @@
|
| #include "net/base/external_estimate_provider.h"
|
| #include "net/base/load_flags.h"
|
| #include "net/base/network_change_notifier.h"
|
| +#include "net/base/socket_performance_watcher_factory.h"
|
| #include "net/http/http_status_code.h"
|
| #include "net/test/embedded_test_server/embedded_test_server.h"
|
| #include "net/test/embedded_test_server/http_request.h"
|
| @@ -157,6 +158,45 @@ class TestThroughputObserver
|
| std::vector<Observation> observations_;
|
| };
|
|
|
| +class TestPacketLossObserver
|
| + : public net::NetworkQualityEstimator::PacketLossObserver {
|
| + public:
|
| + struct Observation {
|
| + Observation(uint64_t num_packets_lost,
|
| + uint64_t num_packets_received_in_order,
|
| + uint64_t num_packets_received_not_in_order,
|
| + const base::TimeTicks& ts,
|
| + net::NetworkQualityEstimator::ObservationSource src)
|
| + : num_packets_lost(num_packets_lost),
|
| + num_packets_received_in_order(num_packets_received_in_order),
|
| + num_packets_received_not_in_order(num_packets_received_not_in_order),
|
| + timestamp(ts),
|
| + source(src) {}
|
| + uint64_t num_packets_lost;
|
| + uint64_t num_packets_received_in_order;
|
| + uint64_t num_packets_received_not_in_order;
|
| + base::TimeTicks timestamp;
|
| + net::NetworkQualityEstimator::ObservationSource source;
|
| + };
|
| +
|
| + std::vector<Observation>& observations() { return observations_; }
|
| +
|
| + // PacketLossObserver implementation:
|
| + void OnPacketLossObservation(
|
| + uint64_t num_packets_lost,
|
| + uint64_t num_packets_received_in_order,
|
| + uint64_t num_packets_received_not_in_order,
|
| + const base::TimeTicks& timestamp,
|
| + net::NetworkQualityEstimator::ObservationSource source) override {
|
| + observations_.push_back(
|
| + Observation(num_packets_lost, num_packets_received_in_order,
|
| + num_packets_received_not_in_order, timestamp, source));
|
| + }
|
| +
|
| + private:
|
| + std::vector<Observation> observations_;
|
| +};
|
| +
|
| } // namespace
|
|
|
| namespace net {
|
| @@ -255,6 +295,64 @@ TEST(NetworkQualityEstimatorTest, TestKbpsRTTUpdates) {
|
| EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
|
| }
|
|
|
| +// Tests that packet loss rate is updated correctly.
|
| +TEST(NetworkQualityEstimatorTest, TestPacketLossRateUpdates) {
|
| + base::HistogramTester histogram_tester;
|
| + std::map<std::string, std::string> variation_params;
|
| + TestNetworkQualityEstimator estimator(variation_params);
|
| + histogram_tester.ExpectTotalCount("NQE.PacketLossRate.Unknown", 0);
|
| +
|
| + float packet_loss_rate = NetworkQualityEstimator::kInvalidPacketLossRate;
|
| + EXPECT_FALSE(estimator.GetPacketLossRateEstimate(&packet_loss_rate));
|
| +
|
| + estimator.OnUpdatedPacketCountAvailable(
|
| + NetworkQualityEstimator::PROTOCOL_QUIC, 0, 1, 1);
|
| +
|
| + EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate));
|
| + EXPECT_NEAR(0.0, packet_loss_rate, 0.001);
|
| +
|
| + // Check UMA histograms.
|
| + estimator.SimulateNetworkChangeTo(
|
| + NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, std::string());
|
| + histogram_tester.ExpectTotalCount("NQE.PacketLossRate.Unknown", 1);
|
| +
|
| + EXPECT_FALSE(estimator.GetPacketLossRateEstimate(&packet_loss_rate));
|
| +
|
| + // Expecting packet number p, but received packet number p+9. 1 out of 10
|
| + // packets were received.
|
| + estimator.OnUpdatedPacketCountAvailable(
|
| + NetworkQualityEstimator::PROTOCOL_QUIC, 9, 1, 0);
|
| + EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate));
|
| + EXPECT_NEAR(9.0 / 10, packet_loss_rate, 0.001);
|
| +
|
| + // Expecting packet number p+10, and received packet number p+10. Now, 2 out
|
| + // of 11 packets were received.
|
| + estimator.OnUpdatedPacketCountAvailable(
|
| + NetworkQualityEstimator::PROTOCOL_QUIC, 0, 1, 0);
|
| + EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate));
|
| + EXPECT_NEAR(9.0 / 11, packet_loss_rate, 0.001);
|
| +
|
| + // Expecting packet number p+11, and received packet number p+11. Now, 3 out
|
| + // of 12 packets were received.
|
| + estimator.OnUpdatedPacketCountAvailable(
|
| + NetworkQualityEstimator::PROTOCOL_QUIC, 0, 1, 0);
|
| + EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate));
|
| + EXPECT_NEAR(9.0 / 12, packet_loss_rate, 0.001);
|
| +
|
| + // Expecting packet number p+12, but received packet number p. Still, 3 out of
|
| + // 12 packets were received.
|
| + estimator.OnUpdatedPacketCountAvailable(
|
| + NetworkQualityEstimator::PROTOCOL_QUIC, 0, 0, 1);
|
| + EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate));
|
| + EXPECT_NEAR(9.0 / 12, packet_loss_rate, 0.001);
|
| +
|
| + estimator.SimulateNetworkChangeTo(
|
| + NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, std::string());
|
| + histogram_tester.ExpectTotalCount("NQE.PacketLossRate.WiFi", 1);
|
| +
|
| + EXPECT_FALSE(estimator.GetPacketLossRateEstimate(&packet_loss_rate));
|
| +}
|
| +
|
| TEST(NetworkQualityEstimatorTest, StoreObservations) {
|
| std::map<std::string, std::string> variation_params;
|
| TestNetworkQualityEstimator estimator(variation_params);
|
| @@ -299,6 +397,8 @@ TEST(NetworkQualityEstimatorTest, PercentileSameTimestamps) {
|
| EXPECT_FALSE(estimator.GetRTTEstimate(&rtt));
|
| int32_t kbps;
|
| EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
|
| + float packet_loss_rate = NetworkQualityEstimator::kInvalidPacketLossRate;
|
| + EXPECT_FALSE(estimator.GetPacketLossRateEstimate(&packet_loss_rate));
|
|
|
| // Insert samples from {1,2,3,..., 100}. First insert odd samples, then even
|
| // samples. This helps in verifying that the order of samples does not matter.
|
| @@ -310,8 +410,12 @@ TEST(NetworkQualityEstimatorTest, PercentileSameTimestamps) {
|
| NetworkQualityEstimator::RttObservation(
|
| base::TimeDelta::FromMilliseconds(i), now,
|
| NetworkQualityEstimator::URL_REQUEST));
|
| + estimator.packet_loss_rate_observations_.AddObservation(
|
| + NetworkQualityEstimator::PacketLossObservation(
|
| + 0.0, now, NetworkQualityEstimator::QUIC));
|
| EXPECT_TRUE(estimator.GetRTTEstimate(&rtt));
|
| EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
|
| + EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate));
|
| }
|
|
|
| for (int i = 2; i <= 100; i += 2) {
|
| @@ -322,8 +426,12 @@ TEST(NetworkQualityEstimatorTest, PercentileSameTimestamps) {
|
| NetworkQualityEstimator::RttObservation(
|
| base::TimeDelta::FromMilliseconds(i), now,
|
| NetworkQualityEstimator::URL_REQUEST));
|
| + estimator.packet_loss_rate_observations_.AddObservation(
|
| + NetworkQualityEstimator::PacketLossObservation(
|
| + 1.0, now, NetworkQualityEstimator::QUIC));
|
| EXPECT_TRUE(estimator.GetRTTEstimate(&rtt));
|
| EXPECT_TRUE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps));
|
| + EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate));
|
| }
|
|
|
| for (int i = 0; i <= 100; ++i) {
|
| @@ -346,6 +454,8 @@ TEST(NetworkQualityEstimatorTest, PercentileSameTimestamps) {
|
| base::TimeTicks(), 50) > 0);
|
| EXPECT_TRUE(estimator.GetRTTEstimateInternal(base::TimeTicks(), 50) !=
|
| NetworkQualityEstimator::InvalidRTT());
|
| + EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate));
|
| + EXPECT_NEAR(0.5, packet_loss_rate, 0.001);
|
| }
|
|
|
| // Verifies that the percentiles are correctly computed. Observations have
|
| @@ -359,6 +469,9 @@ TEST(NetworkQualityEstimatorTest, PercentileDifferentTimestamps) {
|
| base::TimeTicks now = base::TimeTicks::Now();
|
| base::TimeTicks very_old = base::TimeTicks::UnixEpoch();
|
|
|
| + float packet_loss_rate = NetworkQualityEstimator::kInvalidPacketLossRate;
|
| + EXPECT_FALSE(estimator.GetPacketLossRateEstimate(&packet_loss_rate));
|
| +
|
| // First 50 samples have very old timestamp.
|
| for (int i = 1; i <= 50; ++i) {
|
| estimator.downstream_throughput_kbps_observations_.AddObservation(
|
| @@ -368,6 +481,9 @@ TEST(NetworkQualityEstimatorTest, PercentileDifferentTimestamps) {
|
| NetworkQualityEstimator::RttObservation(
|
| base::TimeDelta::FromMilliseconds(i), very_old,
|
| NetworkQualityEstimator::URL_REQUEST));
|
| + estimator.packet_loss_rate_observations_.AddObservation(
|
| + NetworkQualityEstimator::PacketLossObservation(
|
| + 0.0, very_old, NetworkQualityEstimator::QUIC));
|
| }
|
|
|
| // Next 50 (i.e., from 51 to 100) have recent timestamp.
|
| @@ -379,6 +495,9 @@ TEST(NetworkQualityEstimatorTest, PercentileDifferentTimestamps) {
|
| NetworkQualityEstimator::RttObservation(
|
| base::TimeDelta::FromMilliseconds(i), now,
|
| NetworkQualityEstimator::URL_REQUEST));
|
| + estimator.packet_loss_rate_observations_.AddObservation(
|
| + NetworkQualityEstimator::PacketLossObservation(
|
| + 1.0, now, NetworkQualityEstimator::QUIC));
|
| }
|
|
|
| // Older samples have very little weight. So, all percentiles are >= 51
|
| @@ -402,6 +521,9 @@ TEST(NetworkQualityEstimatorTest, PercentileDifferentTimestamps) {
|
| EXPECT_EQ(NetworkQualityEstimator::kInvalidThroughput,
|
| estimator.GetDownlinkThroughputKbpsEstimateInternal(
|
| base::TimeTicks::Now() + base::TimeDelta::FromMinutes(10), 50));
|
| +
|
| + EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate));
|
| + EXPECT_NEAR(1.0, packet_loss_rate, 0.001);
|
| }
|
|
|
| // This test notifies NetworkQualityEstimator of received data. Next,
|
| @@ -1026,10 +1148,12 @@ TEST(NetworkQualityEstimatorTest, TestExternalEstimateProviderMergeEstimates) {
|
| TEST(NetworkQualityEstimatorTest, TestObservers) {
|
| TestRTTObserver rtt_observer;
|
| TestThroughputObserver throughput_observer;
|
| + TestPacketLossObserver packet_loss_observer;
|
| std::map<std::string, std::string> variation_params;
|
| TestNetworkQualityEstimator estimator(variation_params);
|
| estimator.AddRTTObserver(&rtt_observer);
|
| estimator.AddThroughputObserver(&throughput_observer);
|
| + estimator.AddPacketLossObserver(&packet_loss_observer);
|
|
|
| TestDelegate test_delegate;
|
| TestURLRequestContext context(true);
|
| @@ -1052,6 +1176,14 @@ TEST(NetworkQualityEstimatorTest, TestObservers) {
|
| request2->Start();
|
| base::RunLoop().Run();
|
|
|
| + float packet_loss_rate = NetworkQualityEstimator::kInvalidPacketLossRate;
|
| + EXPECT_FALSE(estimator.GetPacketLossRateEstimate(&packet_loss_rate));
|
| +
|
| + estimator.OnUpdatedPacketCountAvailable(
|
| + NetworkQualityEstimator::PROTOCOL_QUIC, 0, 1, 1);
|
| + EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate));
|
| + EXPECT_NEAR(0.0, packet_loss_rate, 0.001);
|
| +
|
| // Both RTT and downstream throughput should be updated.
|
| EXPECT_NE(NetworkQualityEstimator::InvalidRTT(),
|
| estimator.GetRTTEstimateInternal(base::TimeTicks(), 100));
|
| @@ -1061,6 +1193,7 @@ TEST(NetworkQualityEstimatorTest, TestObservers) {
|
|
|
| EXPECT_EQ(2U, rtt_observer.observations().size());
|
| EXPECT_EQ(2U, throughput_observer.observations().size());
|
| + ASSERT_EQ(1U, packet_loss_observer.observations().size());
|
| for (auto observation : rtt_observer.observations()) {
|
| EXPECT_LE(0, observation.rtt_ms);
|
| EXPECT_LE(0, (observation.timestamp - then).InMilliseconds());
|
| @@ -1071,6 +1204,13 @@ TEST(NetworkQualityEstimatorTest, TestObservers) {
|
| EXPECT_LE(0, (observation.timestamp - then).InMilliseconds());
|
| EXPECT_EQ(NetworkQualityEstimator::URL_REQUEST, observation.source);
|
| }
|
| + for (auto observation : packet_loss_observer.observations()) {
|
| + EXPECT_LE(0u, observation.num_packets_lost);
|
| + EXPECT_LE(1u, observation.num_packets_received_in_order);
|
| + EXPECT_LE(0u, observation.num_packets_received_not_in_order);
|
| + EXPECT_LE(0, (observation.timestamp - then).InMilliseconds());
|
| + EXPECT_EQ(NetworkQualityEstimator::QUIC, observation.source);
|
| + }
|
|
|
| // Verify that observations from TCP and QUIC are passed on to the observers.
|
| base::TimeDelta tcp_rtt(base::TimeDelta::FromMilliseconds(1));
|
|
|