| 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 <stdint.h> | 7 #include <stdint.h> |
| 8 #include <netinet/tcp.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/http/http_network_session.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" |
| 34 #include "net/url_request/url_request.h" |
| 30 #include "net/url_request/url_request_test_util.h" | 35 #include "net/url_request/url_request_test_util.h" |
| 31 #include "testing/gtest/include/gtest/gtest.h" | 36 #include "testing/gtest/include/gtest/gtest.h" |
| 32 #include "url/gurl.h" | 37 #include "url/gurl.h" |
| 33 | 38 |
| 34 namespace { | 39 namespace { |
| 35 | 40 |
| 36 // Helps in setting the current network type and id. | 41 // Helps in setting the current network type and id. |
| 37 class TestNetworkQualityEstimator : public net::NetworkQualityEstimator { | 42 class TestNetworkQualityEstimator : public net::NetworkQualityEstimator { |
| 38 public: | 43 public: |
| 39 TestNetworkQualityEstimator( | 44 TestNetworkQualityEstimator( |
| 40 const std::map<std::string, std::string>& variation_params, | 45 const std::map<std::string, std::string>& variation_params, |
| 41 scoped_ptr<net::ExternalEstimateProvider> external_estimate_provider) | 46 scoped_ptr<net::ExternalEstimateProvider> external_estimate_provider) |
| 42 : NetworkQualityEstimator(std::move(external_estimate_provider), | 47 : NetworkQualityEstimator(std::move(external_estimate_provider), |
| 43 variation_params, | 48 variation_params, |
| 44 true, | 49 true, |
| 45 true) { | 50 true), |
| 51 watcher_reset_notification_received_(false) { |
| 46 // Set up embedded test server. | 52 // Set up embedded test server. |
| 47 embedded_test_server_.ServeFilesFromDirectory( | 53 embedded_test_server_.ServeFilesFromDirectory( |
| 48 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); | 54 base::FilePath(FILE_PATH_LITERAL("net/data/url_request_unittest"))); |
| 49 EXPECT_TRUE(embedded_test_server_.Start()); | 55 EXPECT_TRUE(embedded_test_server_.Start()); |
| 50 embedded_test_server_.RegisterRequestHandler(base::Bind( | 56 embedded_test_server_.RegisterRequestHandler(base::Bind( |
| 51 &TestNetworkQualityEstimator::HandleRequest, base::Unretained(this))); | 57 &TestNetworkQualityEstimator::HandleRequest, base::Unretained(this))); |
| 52 } | 58 } |
| 53 | 59 |
| 54 explicit TestNetworkQualityEstimator( | 60 explicit TestNetworkQualityEstimator( |
| 55 const std::map<std::string, std::string>& variation_params) | 61 const std::map<std::string, std::string>& variation_params) |
| (...skipping 21 matching lines...) Expand all Loading... |
| 77 http_response->set_content("hello"); | 83 http_response->set_content("hello"); |
| 78 http_response->set_content_type("text/plain"); | 84 http_response->set_content_type("text/plain"); |
| 79 return std::move(http_response); | 85 return std::move(http_response); |
| 80 } | 86 } |
| 81 | 87 |
| 82 // Returns a GURL hosted at embedded test server. | 88 // Returns a GURL hosted at embedded test server. |
| 83 const GURL GetEchoURL() const { | 89 const GURL GetEchoURL() const { |
| 84 return embedded_test_server_.GetURL("/echo.html"); | 90 return embedded_test_server_.GetURL("/echo.html"); |
| 85 } | 91 } |
| 86 | 92 |
| 93 void OnWatcherReset() override { |
| 94 watcher_reset_notification_received_ = true; |
| 95 } |
| 96 |
| 97 bool watcher_reset_notification_received() const { |
| 98 return watcher_reset_notification_received_; |
| 99 } |
| 100 |
| 87 using NetworkQualityEstimator::ReadCachedNetworkQualityEstimate; | 101 using NetworkQualityEstimator::ReadCachedNetworkQualityEstimate; |
| 88 using NetworkQualityEstimator::OnConnectionTypeChanged; | 102 using NetworkQualityEstimator::OnConnectionTypeChanged; |
| 89 | 103 |
| 90 private: | 104 private: |
| 91 // NetworkQualityEstimator implementation that returns the overridden network | 105 // NetworkQualityEstimator implementation that returns the overridden network |
| 92 // id (instead of invoking platform APIs). | 106 // id (instead of invoking platform APIs). |
| 93 NetworkQualityEstimator::NetworkID GetCurrentNetworkID() const override { | 107 NetworkQualityEstimator::NetworkID GetCurrentNetworkID() const override { |
| 94 return NetworkQualityEstimator::NetworkID(current_network_type_, | 108 return NetworkQualityEstimator::NetworkID(current_network_type_, |
| 95 current_network_id_); | 109 current_network_id_); |
| 96 } | 110 } |
| 97 | 111 |
| 98 net::NetworkChangeNotifier::ConnectionType current_network_type_; | 112 net::NetworkChangeNotifier::ConnectionType current_network_type_; |
| 99 std::string current_network_id_; | 113 std::string current_network_id_; |
| 100 | 114 |
| 101 // Embedded server used for testing. | 115 // Embedded server used for testing. |
| 102 net::EmbeddedTestServer embedded_test_server_; | 116 net::EmbeddedTestServer embedded_test_server_; |
| 103 | 117 |
| 118 bool watcher_reset_notification_received_; |
| 119 |
| 104 DISALLOW_COPY_AND_ASSIGN(TestNetworkQualityEstimator); | 120 DISALLOW_COPY_AND_ASSIGN(TestNetworkQualityEstimator); |
| 105 }; | 121 }; |
| 106 | 122 |
| 107 class TestRTTObserver : public net::NetworkQualityEstimator::RTTObserver { | 123 class TestRTTObserver : public net::NetworkQualityEstimator::RTTObserver { |
| 108 public: | 124 public: |
| 109 struct Observation { | 125 struct Observation { |
| 110 Observation(int32_t ms, | 126 Observation(int32_t ms, |
| 111 const base::TimeTicks& ts, | 127 const base::TimeTicks& ts, |
| 112 net::NetworkQualityEstimator::ObservationSource src) | 128 net::NetworkQualityEstimator::ObservationSource src) |
| 113 : rtt_ms(ms), timestamp(ts), source(src) {} | 129 : rtt_ms(ms), timestamp(ts), source(src) {} |
| (...skipping 972 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 1086 quic_watcher->OnUpdatedRTTAvailable(quic_rtt); | 1102 quic_watcher->OnUpdatedRTTAvailable(quic_rtt); |
| 1087 | 1103 |
| 1088 EXPECT_EQ(4U, rtt_observer.observations().size()); | 1104 EXPECT_EQ(4U, rtt_observer.observations().size()); |
| 1089 EXPECT_EQ(2U, throughput_observer.observations().size()); | 1105 EXPECT_EQ(2U, throughput_observer.observations().size()); |
| 1090 | 1106 |
| 1091 EXPECT_EQ(tcp_rtt.InMilliseconds(), rtt_observer.observations().at(2).rtt_ms); | 1107 EXPECT_EQ(tcp_rtt.InMilliseconds(), rtt_observer.observations().at(2).rtt_ms); |
| 1092 EXPECT_EQ(quic_rtt.InMilliseconds(), | 1108 EXPECT_EQ(quic_rtt.InMilliseconds(), |
| 1093 rtt_observer.observations().at(3).rtt_ms); | 1109 rtt_observer.observations().at(3).rtt_ms); |
| 1094 } | 1110 } |
| 1095 | 1111 |
| 1112 // TestTCPSocketRTT requires kernel support for tcp_info struct, and so it is |
| 1113 // enabled only on the Linux platform. |
| 1114 #if defined(TCP_INFO) |
| 1115 #define MAYBE_TestTCPSocketRTT TestTCPSocketRTT |
| 1116 #else |
| 1117 #define MAYBE_TestTCPSocketRTT DISABLED_TestTCPSocketRTT |
| 1118 #endif |
| 1119 // Tests that the TCP socket notifies the Network Quality Estimator of TCP RTTs, |
| 1120 // which in turn notifies registered RTT observers. |
| 1121 TEST(NetworkQualityEstimatorTest, MAYBE_TestTCPSocketRTT) { |
| 1122 TestRTTObserver rtt_observer; |
| 1123 std::map<std::string, std::string> variation_params; |
| 1124 TestNetworkQualityEstimator estimator(variation_params); |
| 1125 estimator.AddRTTObserver(&rtt_observer); |
| 1126 |
| 1127 TestDelegate test_delegate; |
| 1128 TestURLRequestContext context(true); |
| 1129 context.set_network_quality_estimator(&estimator); |
| 1130 |
| 1131 scoped_ptr<HttpNetworkSession::Params> params(new HttpNetworkSession::Params); |
| 1132 // |estimator| should be notified of TCP RTT observations. |
| 1133 params->socket_performance_watcher_factory = &estimator; |
| 1134 context.set_http_network_session_params(std::move(params)); |
| 1135 context.Init(); |
| 1136 |
| 1137 EXPECT_EQ(0U, rtt_observer.observations().size()); |
| 1138 EXPECT_FALSE(estimator.watcher_reset_notification_received()); |
| 1139 |
| 1140 // Send two requests. Verify that the completion of each request generates at |
| 1141 // least one TCP RTT observation. |
| 1142 for (size_t i = 0; i < 2; ++i) { |
| 1143 size_t before_count_tcp_rtt_observations = 0; |
| 1144 for (auto observation : rtt_observer.observations()) { |
| 1145 if (observation.source == NetworkQualityEstimator::TCP) |
| 1146 ++before_count_tcp_rtt_observations; |
| 1147 } |
| 1148 |
| 1149 scoped_ptr<URLRequest> request(context.CreateRequest( |
| 1150 estimator.GetEchoURL(), DEFAULT_PRIORITY, &test_delegate)); |
| 1151 request->Start(); |
| 1152 base::RunLoop().Run(); |
| 1153 |
| 1154 size_t after_count_tcp_rtt_observations = 0; |
| 1155 for (auto observation : rtt_observer.observations()) { |
| 1156 if (observation.source == NetworkQualityEstimator::TCP) |
| 1157 ++after_count_tcp_rtt_observations; |
| 1158 } |
| 1159 EXPECT_LT(before_count_tcp_rtt_observations, |
| 1160 after_count_tcp_rtt_observations) |
| 1161 << i; |
| 1162 } |
| 1163 |
| 1164 EXPECT_TRUE(estimator.watcher_reset_notification_received()); |
| 1165 } |
| 1166 |
| 1096 } // namespace net | 1167 } // namespace net |
| OLD | NEW |