| 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/nqe/network_quality_estimator.h" | 5 #include "net/nqe/network_quality_estimator.h" |
| 6 | 6 |
| 7 #include <stddef.h> | 7 #include <stddef.h> |
| 8 #include <stdint.h> | 8 #include <stdint.h> |
| 9 | 9 |
| 10 #include <limits> | 10 #include <limits> |
| 11 #include <map> | 11 #include <map> |
| 12 #include <memory> | 12 #include <memory> |
| 13 #include <string> | 13 #include <string> |
| 14 #include <utility> | 14 #include <utility> |
| 15 #include <vector> | 15 #include <vector> |
| 16 | 16 |
| 17 #include "base/files/file_path.h" | 17 #include "base/files/file_path.h" |
| 18 #include "base/logging.h" | 18 #include "base/logging.h" |
| 19 #include "base/macros.h" | 19 #include "base/macros.h" |
| 20 #include "base/metrics/histogram_samples.h" | 20 #include "base/metrics/histogram_samples.h" |
| 21 #include "base/run_loop.h" | 21 #include "base/run_loop.h" |
| 22 #include "base/strings/string_number_conversions.h" | 22 #include "base/strings/string_number_conversions.h" |
| 23 #include "base/test/histogram_tester.h" | 23 #include "base/test/histogram_tester.h" |
| 24 #include "base/test/simple_test_tick_clock.h" |
| 24 #include "base/time/time.h" | 25 #include "base/time/time.h" |
| 25 #include "build/build_config.h" | 26 #include "build/build_config.h" |
| 26 #include "net/base/load_flags.h" | 27 #include "net/base/load_flags.h" |
| 27 #include "net/base/network_change_notifier.h" | 28 #include "net/base/network_change_notifier.h" |
| 28 #include "net/http/http_status_code.h" | 29 #include "net/http/http_status_code.h" |
| 29 #include "net/nqe/external_estimate_provider.h" | 30 #include "net/nqe/external_estimate_provider.h" |
| 30 #include "net/nqe/network_quality_observation.h" | 31 #include "net/nqe/network_quality_observation.h" |
| 31 #include "net/nqe/network_quality_observation_source.h" | 32 #include "net/nqe/network_quality_observation_source.h" |
| 32 #include "net/nqe/observation_buffer.h" | 33 #include "net/nqe/observation_buffer.h" |
| 33 #include "net/socket/socket_performance_watcher.h" | 34 #include "net/socket/socket_performance_watcher.h" |
| (...skipping 23 matching lines...) Expand all Loading... |
| 57 | 58 |
| 58 TestNetworkQualityEstimator( | 59 TestNetworkQualityEstimator( |
| 59 std::unique_ptr<net::ExternalEstimateProvider> external_estimate_provider, | 60 std::unique_ptr<net::ExternalEstimateProvider> external_estimate_provider, |
| 60 const std::map<std::string, std::string>& variation_params, | 61 const std::map<std::string, std::string>& variation_params, |
| 61 bool allow_local_host_requests_for_tests, | 62 bool allow_local_host_requests_for_tests, |
| 62 bool allow_smaller_responses_for_tests) | 63 bool allow_smaller_responses_for_tests) |
| 63 : NetworkQualityEstimator(std::move(external_estimate_provider), | 64 : NetworkQualityEstimator(std::move(external_estimate_provider), |
| 64 variation_params, | 65 variation_params, |
| 65 allow_local_host_requests_for_tests, | 66 allow_local_host_requests_for_tests, |
| 66 allow_smaller_responses_for_tests), | 67 allow_smaller_responses_for_tests), |
| 67 current_network_simulated_(false), | 68 effective_connection_type_set_(false), |
| 69 effective_connection_type_(EFFECTIVE_CONNECTION_TYPE_UNKNOWN), |
| 70 current_network_type_(NetworkChangeNotifier::CONNECTION_UNKNOWN), |
| 68 url_rtt_set_(false), | 71 url_rtt_set_(false), |
| 69 downlink_throughput_kbps_set_(false) { | 72 downlink_throughput_kbps_set_(false) { |
| 70 // Set up embedded test server. | 73 // Set up embedded test server. |
| 71 embedded_test_server_.ServeFilesFromDirectory( | 74 embedded_test_server_.ServeFilesFromDirectory( |
| 72 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); | 75 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); |
| 73 EXPECT_TRUE(embedded_test_server_.Start()); | 76 EXPECT_TRUE(embedded_test_server_.Start()); |
| 74 embedded_test_server_.RegisterRequestHandler(base::Bind( | 77 embedded_test_server_.RegisterRequestHandler(base::Bind( |
| 75 &TestNetworkQualityEstimator::HandleRequest, base::Unretained(this))); | 78 &TestNetworkQualityEstimator::HandleRequest, base::Unretained(this))); |
| 76 } | 79 } |
| 77 | 80 |
| 78 explicit TestNetworkQualityEstimator( | 81 explicit TestNetworkQualityEstimator( |
| 79 const std::map<std::string, std::string>& variation_params) | 82 const std::map<std::string, std::string>& variation_params) |
| 80 : TestNetworkQualityEstimator( | 83 : TestNetworkQualityEstimator( |
| 81 variation_params, | 84 variation_params, |
| 82 std::unique_ptr<ExternalEstimateProvider>()) {} | 85 std::unique_ptr<ExternalEstimateProvider>()) {} |
| 83 | 86 |
| 84 ~TestNetworkQualityEstimator() override {} | 87 ~TestNetworkQualityEstimator() override {} |
| 85 | 88 |
| 86 // Overrides the current network type and id. | 89 // Overrides the current network type and id. |
| 87 // Notifies network quality estimator of change in connection. | 90 // Notifies network quality estimator of change in connection. |
| 88 void SimulateNetworkChangeTo(NetworkChangeNotifier::ConnectionType type, | 91 void SimulateNetworkChangeTo(NetworkChangeNotifier::ConnectionType type, |
| 89 const std::string& network_id) { | 92 const std::string& network_id) { |
| 90 current_network_simulated_ = true; | |
| 91 current_network_type_ = type; | 93 current_network_type_ = type; |
| 92 current_network_id_ = network_id; | 94 current_network_id_ = network_id; |
| 93 OnConnectionTypeChanged(type); | 95 OnConnectionTypeChanged(type); |
| 94 } | 96 } |
| 95 | 97 |
| 96 // Called by embedded server when a HTTP request is received. | 98 // Called by embedded server when a HTTP request is received. |
| 97 std::unique_ptr<test_server::HttpResponse> HandleRequest( | 99 std::unique_ptr<test_server::HttpResponse> HandleRequest( |
| 98 const test_server::HttpRequest& request) { | 100 const test_server::HttpRequest& request) { |
| 99 std::unique_ptr<test_server::BasicHttpResponse> http_response( | 101 std::unique_ptr<test_server::BasicHttpResponse> http_response( |
| 100 new test_server::BasicHttpResponse()); | 102 new test_server::BasicHttpResponse()); |
| 101 http_response->set_code(HTTP_OK); | 103 http_response->set_code(HTTP_OK); |
| 102 http_response->set_content("hello"); | 104 http_response->set_content("hello"); |
| 103 http_response->set_content_type("text/plain"); | 105 http_response->set_content_type("text/plain"); |
| 104 return std::move(http_response); | 106 return std::move(http_response); |
| 105 } | 107 } |
| 106 | 108 |
| 107 // Returns a GURL hosted at embedded test server. | 109 // Returns a GURL hosted at embedded test server. |
| 108 const GURL GetEchoURL() const { | 110 const GURL GetEchoURL() const { |
| 109 return embedded_test_server_.GetURL("/echo.html"); | 111 return embedded_test_server_.GetURL("/echo.html"); |
| 110 } | 112 } |
| 111 | 113 |
| 112 void set_url_rtt(const base::TimeDelta& url_rtt) { | 114 void set_url_rtt(const base::TimeDelta& url_rtt) { |
| 113 url_rtt_set_ = true; | 115 url_rtt_set_ = true; |
| 114 url_rtt_ = url_rtt; | 116 url_rtt_ = url_rtt; |
| 115 } | 117 } |
| 116 | 118 |
| 119 void set_effective_connection_type(EffectiveConnectionType type) { |
| 120 effective_connection_type_set_ = true; |
| 121 effective_connection_type_ = type; |
| 122 } |
| 123 |
| 124 EffectiveConnectionType GetEffectiveConnectionType() const override { |
| 125 if (effective_connection_type_set_) |
| 126 return effective_connection_type_; |
| 127 return NetworkQualityEstimator::GetEffectiveConnectionType(); |
| 128 } |
| 129 |
| 117 bool GetURLRequestRTTEstimate(base::TimeDelta* rtt) const override { | 130 bool GetURLRequestRTTEstimate(base::TimeDelta* rtt) const override { |
| 118 if (url_rtt_set_) { | 131 if (url_rtt_set_) { |
| 119 *rtt = url_rtt_; | 132 *rtt = url_rtt_; |
| 120 return true; | 133 return true; |
| 121 } | 134 } |
| 122 return NetworkQualityEstimator::GetURLRequestRTTEstimate(rtt); | 135 return NetworkQualityEstimator::GetURLRequestRTTEstimate(rtt); |
| 123 } | 136 } |
| 124 | 137 |
| 125 void set_downlink_throughput_kbps(int32_t downlink_throughput_kbps) { | 138 void set_downlink_throughput_kbps(int32_t downlink_throughput_kbps) { |
| 126 downlink_throughput_kbps_set_ = true; | 139 downlink_throughput_kbps_set_ = true; |
| 127 downlink_throughput_kbps_ = downlink_throughput_kbps; | 140 downlink_throughput_kbps_ = downlink_throughput_kbps; |
| 128 } | 141 } |
| 129 | 142 |
| 130 bool GetDownlinkThroughputKbpsEstimate(int32_t* kbps) const override { | 143 bool GetDownlinkThroughputKbpsEstimate(int32_t* kbps) const override { |
| 131 if (downlink_throughput_kbps_set_) { | 144 if (downlink_throughput_kbps_set_) { |
| 132 *kbps = downlink_throughput_kbps_; | 145 *kbps = downlink_throughput_kbps_; |
| 133 return true; | 146 return true; |
| 134 } | 147 } |
| 135 return NetworkQualityEstimator::GetDownlinkThroughputKbpsEstimate(kbps); | 148 return NetworkQualityEstimator::GetDownlinkThroughputKbpsEstimate(kbps); |
| 136 } | 149 } |
| 137 | 150 |
| 151 using NetworkQualityEstimator::SetTickClockForTesting; |
| 138 using NetworkQualityEstimator::ReadCachedNetworkQualityEstimate; | 152 using NetworkQualityEstimator::ReadCachedNetworkQualityEstimate; |
| 139 using NetworkQualityEstimator::OnConnectionTypeChanged; | 153 using NetworkQualityEstimator::OnConnectionTypeChanged; |
| 140 | 154 |
| 141 private: | 155 private: |
| 142 // True if the network type and network id are currently simulated. This | |
| 143 // ensures that the correctness of the test does not depend on the | |
| 144 // actual network type of the device on which the test is running. | |
| 145 bool current_network_simulated_; | |
| 146 | |
| 147 // NetworkQualityEstimator implementation that returns the overridden network | 156 // NetworkQualityEstimator implementation that returns the overridden network |
| 148 // id (instead of invoking platform APIs). | 157 // id (instead of invoking platform APIs). |
| 149 NetworkQualityEstimator::NetworkID GetCurrentNetworkID() const override { | 158 NetworkQualityEstimator::NetworkID GetCurrentNetworkID() const override { |
| 150 // GetCurrentNetworkID should be called only if the network type is | |
| 151 // currently simulated. | |
| 152 EXPECT_TRUE(current_network_simulated_); | |
| 153 | |
| 154 return NetworkQualityEstimator::NetworkID(current_network_type_, | 159 return NetworkQualityEstimator::NetworkID(current_network_type_, |
| 155 current_network_id_); | 160 current_network_id_); |
| 156 } | 161 } |
| 157 | 162 |
| 163 bool effective_connection_type_set_; |
| 164 EffectiveConnectionType effective_connection_type_; |
| 165 |
| 158 NetworkChangeNotifier::ConnectionType current_network_type_; | 166 NetworkChangeNotifier::ConnectionType current_network_type_; |
| 159 std::string current_network_id_; | 167 std::string current_network_id_; |
| 160 | 168 |
| 161 bool url_rtt_set_; | 169 bool url_rtt_set_; |
| 162 base::TimeDelta url_rtt_; | 170 base::TimeDelta url_rtt_; |
| 163 | 171 |
| 164 bool downlink_throughput_kbps_set_; | 172 bool downlink_throughput_kbps_set_; |
| 165 int32_t downlink_throughput_kbps_; | 173 int32_t downlink_throughput_kbps_; |
| 166 | 174 |
| 167 // Embedded server used for testing. | 175 // Embedded server used for testing. |
| 168 EmbeddedTestServer embedded_test_server_; | 176 EmbeddedTestServer embedded_test_server_; |
| 169 | 177 |
| 170 DISALLOW_COPY_AND_ASSIGN(TestNetworkQualityEstimator); | 178 DISALLOW_COPY_AND_ASSIGN(TestNetworkQualityEstimator); |
| 171 }; | 179 }; |
| 172 | 180 |
| 181 class TestEffectiveConnectionTypeObserver |
| 182 : public NetworkQualityEstimator::EffectiveConnectionTypeObserver { |
| 183 public: |
| 184 std::vector<NetworkQualityEstimator::EffectiveConnectionType>& |
| 185 effective_connection_types() { |
| 186 return effective_connection_types_; |
| 187 } |
| 188 |
| 189 // EffectiveConnectionTypeObserver implementation: |
| 190 void OnEffectiveConnectionTypeChanged( |
| 191 NetworkQualityEstimator::EffectiveConnectionType type) override { |
| 192 effective_connection_types_.push_back(type); |
| 193 } |
| 194 |
| 195 private: |
| 196 std::vector<NetworkQualityEstimator::EffectiveConnectionType> |
| 197 effective_connection_types_; |
| 198 }; |
| 199 |
| 173 class TestRTTObserver : public NetworkQualityEstimator::RTTObserver { | 200 class TestRTTObserver : public NetworkQualityEstimator::RTTObserver { |
| 174 public: | 201 public: |
| 175 struct Observation { | 202 struct Observation { |
| 176 Observation(int32_t ms, | 203 Observation(int32_t ms, |
| 177 const base::TimeTicks& ts, | 204 const base::TimeTicks& ts, |
| 178 NetworkQualityObservationSource src) | 205 NetworkQualityObservationSource src) |
| 179 : rtt_ms(ms), timestamp(ts), source(src) {} | 206 : rtt_ms(ms), timestamp(ts), source(src) {} |
| 180 int32_t rtt_ms; | 207 int32_t rtt_ms; |
| 181 base::TimeTicks timestamp; | 208 base::TimeTicks timestamp; |
| 182 NetworkQualityObservationSource source; | 209 NetworkQualityObservationSource source; |
| (...skipping 1022 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1205 request->Start(); | 1232 request->Start(); |
| 1206 base::RunLoop().Run(); | 1233 base::RunLoop().Run(); |
| 1207 | 1234 |
| 1208 EXPECT_EQ(test.allow_small_localhost_requests, | 1235 EXPECT_EQ(test.allow_small_localhost_requests, |
| 1209 estimator.GetURLRequestRTTEstimate(&rtt)); | 1236 estimator.GetURLRequestRTTEstimate(&rtt)); |
| 1210 EXPECT_EQ(test.allow_small_localhost_requests, | 1237 EXPECT_EQ(test.allow_small_localhost_requests, |
| 1211 estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); | 1238 estimator.GetDownlinkThroughputKbpsEstimate(&kbps)); |
| 1212 } | 1239 } |
| 1213 } | 1240 } |
| 1214 | 1241 |
| 1215 TEST(NetworkQualityEstimatorTest, TestObservers) { | 1242 // Tests that the effective connection type is computed at the specified |
| 1243 // interval, and that the observers are notified of any change. |
| 1244 TEST(NetworkQualityEstimatorTest, TestEffectiveConnectionTypeObserver) { |
| 1245 std::unique_ptr<base::SimpleTestTickClock> tick_clock( |
| 1246 new base::SimpleTestTickClock()); |
| 1247 base::SimpleTestTickClock* tick_clock_ptr = tick_clock.get(); |
| 1248 |
| 1249 TestEffectiveConnectionTypeObserver observer; |
| 1250 std::map<std::string, std::string> variation_params; |
| 1251 TestNetworkQualityEstimator estimator(variation_params); |
| 1252 estimator.AddEffectiveConnectionTypeObserver(&observer); |
| 1253 estimator.SetTickClockForTesting(std::move(tick_clock)); |
| 1254 |
| 1255 TestDelegate test_delegate; |
| 1256 TestURLRequestContext context(true); |
| 1257 context.set_network_quality_estimator(&estimator); |
| 1258 context.Init(); |
| 1259 |
| 1260 EXPECT_EQ(0U, observer.effective_connection_types().size()); |
| 1261 |
| 1262 estimator.set_effective_connection_type( |
| 1263 NetworkQualityEstimator::EFFECTIVE_CONNECTION_TYPE_2G); |
| 1264 tick_clock_ptr->Advance(base::TimeDelta::FromMinutes(60)); |
| 1265 |
| 1266 std::unique_ptr<URLRequest> request(context.CreateRequest( |
| 1267 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); |
| 1268 request->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME); |
| 1269 request->Start(); |
| 1270 base::RunLoop().Run(); |
| 1271 EXPECT_EQ(1U, observer.effective_connection_types().size()); |
| 1272 |
| 1273 // Next request should not trigger recomputation of effective connection type |
| 1274 // since there has been no change in the clock. |
| 1275 std::unique_ptr<URLRequest> request2(context.CreateRequest( |
| 1276 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); |
| 1277 request2->SetLoadFlags(request->load_flags() | LOAD_MAIN_FRAME); |
| 1278 request2->Start(); |
| 1279 base::RunLoop().Run(); |
| 1280 EXPECT_EQ(1U, observer.effective_connection_types().size()); |
| 1281 |
| 1282 // Change in connection type should send out notification to the observers. |
| 1283 estimator.set_effective_connection_type( |
| 1284 NetworkQualityEstimator::EFFECTIVE_CONNECTION_TYPE_3G); |
| 1285 estimator.SimulateNetworkChangeTo(NetworkChangeNotifier::CONNECTION_WIFI, |
| 1286 "test"); |
| 1287 EXPECT_EQ(2U, observer.effective_connection_types().size()); |
| 1288 |
| 1289 // A change in effective connection type does not trigger notification to the |
| 1290 // observers, since it is not accompanied by any new observation or a network |
| 1291 // change event. |
| 1292 estimator.set_effective_connection_type( |
| 1293 NetworkQualityEstimator::EFFECTIVE_CONNECTION_TYPE_3G); |
| 1294 EXPECT_EQ(2U, observer.effective_connection_types().size()); |
| 1295 } |
| 1296 |
| 1297 TEST(NetworkQualityEstimatorTest, TestRttThroughputObservers) { |
| 1216 TestRTTObserver rtt_observer; | 1298 TestRTTObserver rtt_observer; |
| 1217 TestThroughputObserver throughput_observer; | 1299 TestThroughputObserver throughput_observer; |
| 1218 std::map<std::string, std::string> variation_params; | 1300 std::map<std::string, std::string> variation_params; |
| 1219 TestNetworkQualityEstimator estimator(variation_params); | 1301 TestNetworkQualityEstimator estimator(variation_params); |
| 1220 estimator.AddRTTObserver(&rtt_observer); | 1302 estimator.AddRTTObserver(&rtt_observer); |
| 1221 estimator.AddThroughputObserver(&throughput_observer); | 1303 estimator.AddThroughputObserver(&throughput_observer); |
| 1222 | 1304 |
| 1223 TestDelegate test_delegate; | 1305 TestDelegate test_delegate; |
| 1224 TestURLRequestContext context(true); | 1306 TestURLRequestContext context(true); |
| 1225 context.set_network_quality_estimator(&estimator); | 1307 context.set_network_quality_estimator(&estimator); |
| (...skipping 135 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1361 histogram_tester.ExpectBucketCount("NQE.TransportRTT.Percentile50.Unknown", | 1443 histogram_tester.ExpectBucketCount("NQE.TransportRTT.Percentile50.Unknown", |
| 1362 rtt.InMilliseconds(), 1); | 1444 rtt.InMilliseconds(), 1); |
| 1363 histogram_tester.ExpectTotalCount("NQE.TransportRTT.Percentile10.Unknown", 1); | 1445 histogram_tester.ExpectTotalCount("NQE.TransportRTT.Percentile10.Unknown", 1); |
| 1364 histogram_tester.ExpectTotalCount("NQE.TransportRTT.Percentile50.Unknown", 1); | 1446 histogram_tester.ExpectTotalCount("NQE.TransportRTT.Percentile50.Unknown", 1); |
| 1365 histogram_tester.ExpectTotalCount("NQE.TransportRTT.Percentile90.Unknown", 1); | 1447 histogram_tester.ExpectTotalCount("NQE.TransportRTT.Percentile90.Unknown", 1); |
| 1366 histogram_tester.ExpectTotalCount("NQE.TransportRTT.Percentile100.Unknown", | 1448 histogram_tester.ExpectTotalCount("NQE.TransportRTT.Percentile100.Unknown", |
| 1367 1); | 1449 1); |
| 1368 } | 1450 } |
| 1369 | 1451 |
| 1370 } // namespace net | 1452 } // namespace net |
| OLD | NEW |