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 TestPacketCountObserver |
| 165 : public net::NetworkQualityEstimator::PacketCountObserver { |
| 166 public: |
| 167 struct Observation { |
| 168 Observation(size_t packets_missing, |
| 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_missing(packets_missing), |
| 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_missing; |
| 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 // PacketCountObserver implementation: |
| 188 void OnIncrementalPacketCountObservation( |
| 189 size_t packets_missing, |
| 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( |
| 195 Observation(packets_missing, packets_received_in_order, |
| 196 packets_received_out_of_order, 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 359 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
529 } | 572 } |
530 | 573 |
531 TEST(NetworkQualityEstimatorTest, HalfLifeParam) { | 574 TEST(NetworkQualityEstimatorTest, HalfLifeParam) { |
532 // Verifies if |weight_multiplier_per_second_| is set to correct value for | 575 // Verifies if |weight_multiplier_per_second_| is set to correct value for |
533 // various values of half life parameter. | 576 // various values of half life parameter. |
534 std::map<std::string, std::string> variation_params; | 577 std::map<std::string, std::string> variation_params; |
535 { | 578 { |
536 // Half life parameter is not set. Default value of | 579 // Half life parameter is not set. Default value of |
537 // |weight_multiplier_per_second_| should be used. | 580 // |weight_multiplier_per_second_| should be used. |
538 TestNetworkQualityEstimator estimator(variation_params); | 581 TestNetworkQualityEstimator estimator(variation_params); |
539 EXPECT_NEAR(0.988, estimator.downstream_throughput_kbps_observations_ | 582 EXPECT_NEAR(0.988f, estimator.downstream_throughput_kbps_observations_ |
540 .weight_multiplier_per_second_, | 583 .weight_multiplier_per_second_, |
541 0.001); | 584 0.001f); |
542 } | 585 } |
543 | 586 |
544 variation_params["HalfLifeSeconds"] = "-100"; | 587 variation_params["HalfLifeSeconds"] = "-100"; |
545 { | 588 { |
546 // Half life parameter is set to a negative value. Default value of | 589 // Half life parameter is set to a negative value. Default value of |
547 // |weight_multiplier_per_second_| should be used. | 590 // |weight_multiplier_per_second_| should be used. |
548 TestNetworkQualityEstimator estimator(variation_params); | 591 TestNetworkQualityEstimator estimator(variation_params); |
549 EXPECT_NEAR(0.988, estimator.downstream_throughput_kbps_observations_ | 592 EXPECT_NEAR(0.988f, estimator.downstream_throughput_kbps_observations_ |
550 .weight_multiplier_per_second_, | 593 .weight_multiplier_per_second_, |
551 0.001); | 594 0.001f); |
552 } | 595 } |
553 | 596 |
554 variation_params["HalfLifeSeconds"] = "0"; | 597 variation_params["HalfLifeSeconds"] = "0"; |
555 { | 598 { |
556 // Half life parameter is set to zero. Default value of | 599 // Half life parameter is set to zero. Default value of |
557 // |weight_multiplier_per_second_| should be used. | 600 // |weight_multiplier_per_second_| should be used. |
558 TestNetworkQualityEstimator estimator(variation_params); | 601 TestNetworkQualityEstimator estimator(variation_params); |
559 EXPECT_NEAR(0.988, estimator.downstream_throughput_kbps_observations_ | 602 EXPECT_NEAR(0.988f, estimator.downstream_throughput_kbps_observations_ |
560 .weight_multiplier_per_second_, | 603 .weight_multiplier_per_second_, |
561 0.001); | 604 0.001f); |
562 } | 605 } |
563 | 606 |
564 variation_params["HalfLifeSeconds"] = "10"; | 607 variation_params["HalfLifeSeconds"] = "10"; |
565 { | 608 { |
566 // Half life parameter is set to a valid value. | 609 // Half life parameter is set to a valid value. |
567 TestNetworkQualityEstimator estimator(variation_params); | 610 TestNetworkQualityEstimator estimator(variation_params); |
568 EXPECT_NEAR(0.933, estimator.downstream_throughput_kbps_observations_ | 611 EXPECT_NEAR(0.933f, estimator.downstream_throughput_kbps_observations_ |
569 .weight_multiplier_per_second_, | 612 .weight_multiplier_per_second_, |
570 0.001); | 613 0.001f); |
571 } | 614 } |
572 } | 615 } |
573 | 616 |
574 // Test if the network estimates are cached when network change notification | 617 // Test if the network estimates are cached when network change notification |
575 // is invoked. | 618 // is invoked. |
576 TEST(NetworkQualityEstimatorTest, TestCaching) { | 619 TEST(NetworkQualityEstimatorTest, TestCaching) { |
577 std::map<std::string, std::string> variation_params; | 620 std::map<std::string, std::string> variation_params; |
578 TestNetworkQualityEstimator estimator(variation_params); | 621 TestNetworkQualityEstimator estimator(variation_params); |
579 size_t expected_cache_size = 0; | 622 size_t expected_cache_size = 0; |
580 EXPECT_EQ(expected_cache_size, estimator.cached_network_qualities_.size()); | 623 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(); | 1062 request->Start(); |
1020 base::RunLoop().Run(); | 1063 base::RunLoop().Run(); |
1021 | 1064 |
1022 EXPECT_EQ(2U, estimator.rtt_msec_observations_.Size()); | 1065 EXPECT_EQ(2U, estimator.rtt_msec_observations_.Size()); |
1023 EXPECT_EQ(2U, estimator.downstream_throughput_kbps_observations_.Size()); | 1066 EXPECT_EQ(2U, estimator.downstream_throughput_kbps_observations_.Size()); |
1024 } | 1067 } |
1025 | 1068 |
1026 TEST(NetworkQualityEstimatorTest, TestObservers) { | 1069 TEST(NetworkQualityEstimatorTest, TestObservers) { |
1027 TestRTTObserver rtt_observer; | 1070 TestRTTObserver rtt_observer; |
1028 TestThroughputObserver throughput_observer; | 1071 TestThroughputObserver throughput_observer; |
| 1072 TestPacketCountObserver packet_count_observer; |
1029 std::map<std::string, std::string> variation_params; | 1073 std::map<std::string, std::string> variation_params; |
1030 TestNetworkQualityEstimator estimator(variation_params); | 1074 TestNetworkQualityEstimator estimator(variation_params); |
1031 estimator.AddRTTObserver(&rtt_observer); | 1075 estimator.AddRTTObserver(&rtt_observer); |
1032 estimator.AddThroughputObserver(&throughput_observer); | 1076 estimator.AddThroughputObserver(&throughput_observer); |
| 1077 estimator.AddPacketCountObserver(&packet_count_observer); |
1033 | 1078 |
1034 TestDelegate test_delegate; | 1079 TestDelegate test_delegate; |
1035 TestURLRequestContext context(true); | 1080 TestURLRequestContext context(true); |
1036 context.set_network_quality_estimator(&estimator); | 1081 context.set_network_quality_estimator(&estimator); |
1037 context.Init(); | 1082 context.Init(); |
1038 | 1083 |
1039 EXPECT_EQ(0U, rtt_observer.observations().size()); | 1084 EXPECT_EQ(0U, rtt_observer.observations().size()); |
1040 EXPECT_EQ(0U, throughput_observer.observations().size()); | 1085 EXPECT_EQ(0U, throughput_observer.observations().size()); |
1041 base::TimeTicks then = base::TimeTicks::Now(); | 1086 base::TimeTicks then = base::TimeTicks::Now(); |
1042 | 1087 |
1043 scoped_ptr<URLRequest> request(context.CreateRequest( | 1088 scoped_ptr<URLRequest> request(context.CreateRequest( |
1044 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); | 1089 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); |
1045 request->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME); | 1090 request->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME); |
1046 request->Start(); | 1091 request->Start(); |
1047 base::RunLoop().Run(); | 1092 base::RunLoop().Run(); |
1048 | 1093 |
1049 scoped_ptr<URLRequest> request2(context.CreateRequest( | 1094 scoped_ptr<URLRequest> request2(context.CreateRequest( |
1050 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); | 1095 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); |
1051 request2->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME); | 1096 request2->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME); |
1052 request2->Start(); | 1097 request2->Start(); |
1053 base::RunLoop().Run(); | 1098 base::RunLoop().Run(); |
1054 | 1099 |
| 1100 estimator.OnIncrementalPacketCountAvailable( |
| 1101 NetworkQualityEstimator::PROTOCOL_QUIC, 0, 1, 1); |
| 1102 |
1055 // Both RTT and downstream throughput should be updated. | 1103 // Both RTT and downstream throughput should be updated. |
1056 EXPECT_NE(NetworkQualityEstimator::InvalidRTT(), | 1104 EXPECT_NE(NetworkQualityEstimator::InvalidRTT(), |
1057 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); | 1105 estimator.GetRTTEstimateInternal(base::TimeTicks(), 100)); |
1058 EXPECT_NE(NetworkQualityEstimator::kInvalidThroughput, | 1106 EXPECT_NE(NetworkQualityEstimator::kInvalidThroughput, |
1059 estimator.GetDownlinkThroughputKbpsEstimateInternal( | 1107 estimator.GetDownlinkThroughputKbpsEstimateInternal( |
1060 base::TimeTicks(), 100)); | 1108 base::TimeTicks(), 100)); |
1061 | 1109 |
1062 EXPECT_EQ(2U, rtt_observer.observations().size()); | 1110 EXPECT_EQ(2U, rtt_observer.observations().size()); |
1063 EXPECT_EQ(2U, throughput_observer.observations().size()); | 1111 EXPECT_EQ(2U, throughput_observer.observations().size()); |
1064 for (auto observation : rtt_observer.observations()) { | 1112 ASSERT_EQ(1U, packet_count_observer.observations().size()); |
| 1113 for (const auto& observation : rtt_observer.observations()) { |
1065 EXPECT_LE(0, observation.rtt_ms); | 1114 EXPECT_LE(0, observation.rtt_ms); |
1066 EXPECT_LE(0, (observation.timestamp - then).InMilliseconds()); | 1115 EXPECT_LE(0, (observation.timestamp - then).InMilliseconds()); |
1067 EXPECT_EQ(NetworkQualityEstimator::URL_REQUEST, observation.source); | 1116 EXPECT_EQ(NetworkQualityEstimator::URL_REQUEST, observation.source); |
1068 } | 1117 } |
1069 for (auto observation : throughput_observer.observations()) { | 1118 for (const auto& observation : throughput_observer.observations()) { |
1070 EXPECT_LE(0, observation.throughput_kbps); | 1119 EXPECT_LE(0, observation.throughput_kbps); |
1071 EXPECT_LE(0, (observation.timestamp - then).InMilliseconds()); | 1120 EXPECT_LE(0, (observation.timestamp - then).InMilliseconds()); |
1072 EXPECT_EQ(NetworkQualityEstimator::URL_REQUEST, observation.source); | 1121 EXPECT_EQ(NetworkQualityEstimator::URL_REQUEST, observation.source); |
1073 } | 1122 } |
| 1123 for (const auto& observation : packet_count_observer.observations()) { |
| 1124 EXPECT_LE(0u, observation.packets_missing); |
| 1125 EXPECT_LE(1u, observation.packets_received_in_order); |
| 1126 EXPECT_LE(0u, observation.packets_received_out_of_order); |
| 1127 EXPECT_LE(0, (observation.timestamp - then).InMilliseconds()); |
| 1128 EXPECT_EQ(NetworkQualityEstimator::QUIC, observation.source); |
| 1129 } |
1074 | 1130 |
1075 // Verify that observations from TCP and QUIC are passed on to the observers. | 1131 // Verify that observations from TCP and QUIC are passed on to the observers. |
1076 base::TimeDelta tcp_rtt(base::TimeDelta::FromMilliseconds(1)); | 1132 base::TimeDelta tcp_rtt(base::TimeDelta::FromMilliseconds(1)); |
1077 base::TimeDelta quic_rtt(base::TimeDelta::FromMilliseconds(2)); | 1133 base::TimeDelta quic_rtt(base::TimeDelta::FromMilliseconds(2)); |
1078 | 1134 |
1079 scoped_ptr<SocketPerformanceWatcher> tcp_watcher = | 1135 scoped_ptr<SocketPerformanceWatcher> tcp_watcher = |
1080 estimator.CreateSocketPerformanceWatcher( | 1136 estimator.CreateSocketPerformanceWatcher( |
1081 SocketPerformanceWatcherFactory::PROTOCOL_TCP); | 1137 SocketPerformanceWatcherFactory::PROTOCOL_TCP); |
1082 scoped_ptr<SocketPerformanceWatcher> quic_watcher = | 1138 scoped_ptr<SocketPerformanceWatcher> quic_watcher = |
1083 estimator.CreateSocketPerformanceWatcher( | 1139 estimator.CreateSocketPerformanceWatcher( |
1084 SocketPerformanceWatcherFactory::PROTOCOL_QUIC); | 1140 SocketPerformanceWatcherFactory::PROTOCOL_QUIC); |
1085 tcp_watcher->OnUpdatedRTTAvailable(tcp_rtt); | 1141 tcp_watcher->OnUpdatedRTTAvailable(tcp_rtt); |
1086 quic_watcher->OnUpdatedRTTAvailable(quic_rtt); | 1142 quic_watcher->OnUpdatedRTTAvailable(quic_rtt); |
1087 | 1143 |
1088 EXPECT_EQ(4U, rtt_observer.observations().size()); | 1144 EXPECT_EQ(4U, rtt_observer.observations().size()); |
1089 EXPECT_EQ(2U, throughput_observer.observations().size()); | 1145 EXPECT_EQ(2U, throughput_observer.observations().size()); |
1090 | 1146 |
1091 EXPECT_EQ(tcp_rtt.InMilliseconds(), rtt_observer.observations().at(2).rtt_ms); | 1147 EXPECT_EQ(tcp_rtt.InMilliseconds(), rtt_observer.observations().at(2).rtt_ms); |
1092 EXPECT_EQ(quic_rtt.InMilliseconds(), | 1148 EXPECT_EQ(quic_rtt.InMilliseconds(), |
1093 rtt_observer.observations().at(3).rtt_ms); | 1149 rtt_observer.observations().at(3).rtt_ms); |
1094 } | 1150 } |
1095 | 1151 |
1096 } // namespace net | 1152 } // namespace net |
OLD | NEW |