Chromium Code Reviews| 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..ed58c2a1aff6273eee398a13c32006879ba578c7 100644 |
| --- a/net/base/network_quality_estimator_unittest.cc |
| +++ b/net/base/network_quality_estimator_unittest.cc |
| @@ -4,6 +4,7 @@ |
| #include "net/base/network_quality_estimator.h" |
| +#include <stddef.h> |
| #include <stdint.h> |
|
bengr
2016/02/26 23:07:04
Add a blank line after.
tbansal1
2016/02/27 00:03:54
Done.
|
| #include <limits> |
| #include <map> |
| @@ -23,6 +24,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 +159,45 @@ class TestThroughputObserver |
| std::vector<Observation> observations_; |
| }; |
| +class TestPacketLossObserver |
| + : public net::NetworkQualityEstimator::PacketLossObserver { |
| + public: |
| + struct Observation { |
| + Observation(size_t packets_lost, |
| + size_t packets_received_in_order, |
| + size_t packets_received_out_of_order, |
| + const base::TimeTicks& ts, |
| + net::NetworkQualityEstimator::ObservationSource src) |
| + : packets_lost(packets_lost), |
| + packets_received_in_order(packets_received_in_order), |
| + packets_received_out_of_order(packets_received_out_of_order), |
| + timestamp(ts), |
| + source(src) {} |
| + size_t packets_lost; |
| + size_t packets_received_in_order; |
| + size_t packets_received_out_of_order; |
| + base::TimeTicks timestamp; |
| + net::NetworkQualityEstimator::ObservationSource source; |
| + }; |
| + |
| + std::vector<Observation>& observations() { return observations_; } |
| + |
| + // PacketLossObserver implementation: |
| + void OnPacketLossObservation( |
| + size_t packets_lost, |
| + size_t packets_received_in_order, |
| + size_t packets_received_out_of_order, |
| + const base::TimeTicks& timestamp, |
| + net::NetworkQualityEstimator::ObservationSource source) override { |
| + observations_.push_back(Observation(packets_lost, packets_received_in_order, |
| + packets_received_out_of_order, |
| + timestamp, source)); |
| + } |
| + |
| + private: |
| + std::vector<Observation> observations_; |
| +}; |
| + |
| } // namespace |
| namespace net { |
| @@ -255,6 +296,114 @@ TEST(NetworkQualityEstimatorTest, TestKbpsRTTUpdates) { |
| EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); |
| } |
| +// Tests that packet loss rate is updated correctly. |
| +TEST(NetworkQualityEstimatorTest, TestPacketLossRateUpdates) { |
| + std::map<std::string, std::string> variation_params; |
| + TestNetworkQualityEstimator estimator(variation_params); |
| + |
| + float packet_loss_rate; |
| + 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.0f, packet_loss_rate, 0.001f); |
| + |
| + estimator.SimulateNetworkChangeTo( |
| + NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, std::string()); |
| + |
| + EXPECT_FALSE(estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
| + |
| + // Expecting packet number i, but received packet number i+9. 1 out of 10 |
| + // packets have been received. |
| + estimator.OnUpdatedPacketCountAvailable( |
| + NetworkQualityEstimator::PROTOCOL_QUIC, 9, 1, 0); |
| + EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
| + EXPECT_NEAR(9.0f / 10, packet_loss_rate, 0.001f); |
| + |
| + // Expecting packet number i+10, and received packet number i+10. 2 out |
| + // of 11 packets have been received. |
| + estimator.OnUpdatedPacketCountAvailable( |
| + NetworkQualityEstimator::PROTOCOL_QUIC, 0, 1, 0); |
| + EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
| + EXPECT_NEAR(9.0f / 11, packet_loss_rate, 0.001f); |
| + |
| + // Expecting packet number i+11, and received packet number i+11. 3 out |
| + // of 12 packets have been received. |
| + estimator.OnUpdatedPacketCountAvailable( |
| + NetworkQualityEstimator::PROTOCOL_QUIC, 0, 1, 0); |
| + EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
| + EXPECT_NEAR(9.0f / 12, packet_loss_rate, 0.001f); |
| + |
| + // Expecting packet number i+12, but received packet number i. 3 out of |
| + // 12 packets have been received. |
| + estimator.OnUpdatedPacketCountAvailable( |
| + NetworkQualityEstimator::PROTOCOL_QUIC, 0, 0, 1); |
| + EXPECT_TRUE(estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
| + EXPECT_NEAR(9.0f / 12, packet_loss_rate, 0.001f); |
| +} |
| + |
| +// Tests that packet loss UMA histogram is recorded properly. |
| +TEST(NetworkQualityEstimatorTest, TestPacketLossRateHistogram) { |
| + std::map<std::string, std::string> variation_params; |
|
bengr
2016/02/26 23:07:04
#include <string>
tbansal1
2016/02/27 00:03:54
Done.
|
| + TestNetworkQualityEstimator estimator(variation_params); |
| + |
| + TestDelegate test_delegate; |
| + TestURLRequestContext context(true); |
| + context.set_network_quality_estimator(&estimator); |
| + context.Init(); |
| + |
| + const struct { |
| + bool notify_packet_counts; |
| + bool set_mainframe_flag; |
| + } tests[] = { |
| + { |
| + false, false, |
| + }, |
| + { |
| + false, true, |
| + }, |
| + { |
| + true, false, |
| + }, |
| + { |
| + true, true, |
| + }, |
| + }; |
| + |
| + for (auto test : tests) { |
| + base::HistogramTester histogram_tester; |
| + estimator.SimulateNetworkChangeTo( |
| + NetworkChangeNotifier::ConnectionType::CONNECTION_WIFI, "test"); |
| + |
| + float packet_loss_rate; |
| + EXPECT_FALSE(estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
| + |
| + if (test.notify_packet_counts) { |
| + estimator.OnUpdatedPacketCountAvailable( |
| + NetworkQualityEstimator::PROTOCOL_QUIC, 0, 1, 1); |
| + } |
| + EXPECT_EQ(test.notify_packet_counts, |
| + estimator.GetPacketLossRateEstimate(&packet_loss_rate)); |
| + |
| + for (size_t i = 0; i < 2; ++i) { |
| + // Check UMA histograms. |
| + scoped_ptr<URLRequest> request(context.CreateRequest( |
| + estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); |
| + if (test.set_mainframe_flag) { |
| + request->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME); |
| + } |
| + request->Start(); |
| + base::RunLoop().Run(); |
| + size_t expect_histogram_count = |
| + test.notify_packet_counts && test.set_mainframe_flag ? i + 1 : 0; |
| + histogram_tester.ExpectTotalCount("NQE.PacketLossRate.WiFi", |
| + expect_histogram_count); |
| + } |
| + } |
| +} |
| + |
| TEST(NetworkQualityEstimatorTest, StoreObservations) { |
| std::map<std::string, std::string> variation_params; |
| TestNetworkQualityEstimator estimator(variation_params); |
| @@ -299,6 +448,8 @@ TEST(NetworkQualityEstimatorTest, PercentileSameTimestamps) { |
| EXPECT_FALSE(estimator.GetRTTEstimate(&rtt)); |
| int32_t kbps; |
| EXPECT_FALSE(estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); |
| + float packet_loss_rate; |
| + 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 +461,12 @@ TEST(NetworkQualityEstimatorTest, PercentileSameTimestamps) { |
| NetworkQualityEstimator::RttObservation( |
| base::TimeDelta::FromMilliseconds(i), now, |
| NetworkQualityEstimator::URL_REQUEST)); |
| + estimator.packet_loss_rate_observations_.AddObservation( |
| + NetworkQualityEstimator::PacketLossRateObservation( |
| + 0.0f, 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 +477,12 @@ TEST(NetworkQualityEstimatorTest, PercentileSameTimestamps) { |
| NetworkQualityEstimator::RttObservation( |
| base::TimeDelta::FromMilliseconds(i), now, |
| NetworkQualityEstimator::URL_REQUEST)); |
| + estimator.packet_loss_rate_observations_.AddObservation( |
| + NetworkQualityEstimator::PacketLossRateObservation( |
| + 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 +505,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.5f, packet_loss_rate, 0.001f); |
| } |
| // Verifies that the percentiles are correctly computed. Observations have |
| @@ -359,6 +520,9 @@ TEST(NetworkQualityEstimatorTest, PercentileDifferentTimestamps) { |
| base::TimeTicks now = base::TimeTicks::Now(); |
| base::TimeTicks very_old = base::TimeTicks::UnixEpoch(); |
| + float packet_loss_rate; |
| + 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 +532,9 @@ TEST(NetworkQualityEstimatorTest, PercentileDifferentTimestamps) { |
| NetworkQualityEstimator::RttObservation( |
| base::TimeDelta::FromMilliseconds(i), very_old, |
| NetworkQualityEstimator::URL_REQUEST)); |
| + estimator.packet_loss_rate_observations_.AddObservation( |
| + NetworkQualityEstimator::PacketLossRateObservation( |
| + 0.0f, very_old, NetworkQualityEstimator::QUIC)); |
| } |
| // Next 50 (i.e., from 51 to 100) have recent timestamp. |
| @@ -379,6 +546,9 @@ TEST(NetworkQualityEstimatorTest, PercentileDifferentTimestamps) { |
| NetworkQualityEstimator::RttObservation( |
| base::TimeDelta::FromMilliseconds(i), now, |
| NetworkQualityEstimator::URL_REQUEST)); |
| + estimator.packet_loss_rate_observations_.AddObservation( |
| + NetworkQualityEstimator::PacketLossRateObservation( |
| + 1.0, now, NetworkQualityEstimator::QUIC)); |
| } |
| // Older samples have very little weight. So, all percentiles are >= 51 |
| @@ -402,6 +572,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.001f); |
| } |
| // This test notifies NetworkQualityEstimator of received data. Next, |
| @@ -536,9 +709,9 @@ TEST(NetworkQualityEstimatorTest, HalfLifeParam) { |
| // Half life parameter is not set. Default value of |
| // |weight_multiplier_per_second_| should be used. |
| TestNetworkQualityEstimator estimator(variation_params); |
| - EXPECT_NEAR(0.988, estimator.downstream_throughput_kbps_observations_ |
| - .weight_multiplier_per_second_, |
| - 0.001); |
| + EXPECT_NEAR(0.988f, estimator.downstream_throughput_kbps_observations_ |
| + .weight_multiplier_per_second_, |
| + 0.001f); |
| } |
| variation_params["HalfLifeSeconds"] = "-100"; |
| @@ -546,9 +719,9 @@ TEST(NetworkQualityEstimatorTest, HalfLifeParam) { |
| // Half life parameter is set to a negative value. Default value of |
| // |weight_multiplier_per_second_| should be used. |
| TestNetworkQualityEstimator estimator(variation_params); |
| - EXPECT_NEAR(0.988, estimator.downstream_throughput_kbps_observations_ |
| - .weight_multiplier_per_second_, |
| - 0.001); |
| + EXPECT_NEAR(0.988f, estimator.downstream_throughput_kbps_observations_ |
| + .weight_multiplier_per_second_, |
| + 0.001f); |
| } |
| variation_params["HalfLifeSeconds"] = "0"; |
| @@ -556,18 +729,18 @@ TEST(NetworkQualityEstimatorTest, HalfLifeParam) { |
| // Half life parameter is set to zero. Default value of |
| // |weight_multiplier_per_second_| should be used. |
| TestNetworkQualityEstimator estimator(variation_params); |
| - EXPECT_NEAR(0.988, estimator.downstream_throughput_kbps_observations_ |
| - .weight_multiplier_per_second_, |
| - 0.001); |
| + EXPECT_NEAR(0.988f, estimator.downstream_throughput_kbps_observations_ |
| + .weight_multiplier_per_second_, |
| + 0.001f); |
| } |
| variation_params["HalfLifeSeconds"] = "10"; |
| { |
| // Half life parameter is set to a valid value. |
| TestNetworkQualityEstimator estimator(variation_params); |
| - EXPECT_NEAR(0.933, estimator.downstream_throughput_kbps_observations_ |
| - .weight_multiplier_per_second_, |
| - 0.001); |
| + EXPECT_NEAR(0.933f, estimator.downstream_throughput_kbps_observations_ |
| + .weight_multiplier_per_second_, |
| + 0.001f); |
| } |
| } |
| @@ -1026,10 +1199,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 +1227,14 @@ TEST(NetworkQualityEstimatorTest, TestObservers) { |
| request2->Start(); |
| base::RunLoop().Run(); |
| + float packet_loss_rate; |
| + 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.0f, packet_loss_rate, 0.001f); |
| + |
| // Both RTT and downstream throughput should be updated. |
| EXPECT_NE(NetworkQualityEstimator::InvalidRTT(), |
| estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); |
| @@ -1061,6 +1244,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 +1255,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.packets_lost); |
| + EXPECT_LE(1u, observation.packets_received_in_order); |
| + EXPECT_LE(0u, observation.packets_received_out_of_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)); |