| OLD | NEW |
| 1 // Copyright 2016 The Chromium Authors. All rights reserved. | 1 // Copyright 2016 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/throughput_analyzer.h" | 5 #include "net/nqe/throughput_analyzer.h" |
| 6 | 6 |
| 7 #include <stdint.h> | 7 #include <stdint.h> |
| 8 | 8 |
| 9 #include <deque> | 9 #include <deque> |
| 10 #include <map> | 10 #include <map> |
| 11 #include <memory> | 11 #include <memory> |
| 12 #include <string> | 12 #include <string> |
| 13 #include <utility> |
| 14 #include <vector> |
| 13 | 15 |
| 14 #include "base/bind.h" | 16 #include "base/bind.h" |
| 15 #include "base/bind_helpers.h" | 17 #include "base/bind_helpers.h" |
| 16 #include "base/logging.h" | 18 #include "base/logging.h" |
| 17 #include "base/macros.h" | 19 #include "base/macros.h" |
| 20 #include "base/memory/ptr_util.h" |
| 18 #include "base/run_loop.h" | 21 #include "base/run_loop.h" |
| 19 #include "base/single_thread_task_runner.h" | 22 #include "base/single_thread_task_runner.h" |
| 20 #include "base/strings/string_number_conversions.h" | 23 #include "base/strings/string_number_conversions.h" |
| 21 #include "base/threading/thread_task_runner_handle.h" | 24 #include "base/threading/thread_task_runner_handle.h" |
| 22 #include "net/base/url_util.h" | 25 #include "net/dns/mock_host_resolver.h" |
| 26 #include "net/log/test_net_log.h" |
| 23 #include "net/nqe/network_quality_estimator_params.h" | 27 #include "net/nqe/network_quality_estimator_params.h" |
| 28 #include "net/nqe/network_quality_estimator_util.h" |
| 24 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" | 29 #include "net/traffic_annotation/network_traffic_annotation_test_helper.h" |
| 25 #include "net/url_request/url_request.h" | 30 #include "net/url_request/url_request.h" |
| 26 #include "net/url_request/url_request_test_util.h" | 31 #include "net/url_request/url_request_test_util.h" |
| 27 #include "testing/gtest/include/gtest/gtest.h" | 32 #include "testing/gtest/include/gtest/gtest.h" |
| 28 | 33 |
| 29 namespace net { | 34 namespace net { |
| 30 | 35 |
| 31 namespace nqe { | 36 namespace nqe { |
| 32 | 37 |
| 33 namespace { | 38 namespace { |
| 34 | 39 |
| 35 class TestThroughputAnalyzer : public internal::ThroughputAnalyzer { | 40 class TestThroughputAnalyzer : public internal::ThroughputAnalyzer { |
| 36 public: | 41 public: |
| 37 explicit TestThroughputAnalyzer(NetworkQualityEstimatorParams* params) | 42 explicit TestThroughputAnalyzer(NetworkQualityEstimatorParams* params) |
| 38 : internal::ThroughputAnalyzer( | 43 : internal::ThroughputAnalyzer( |
| 39 params, | 44 params, |
| 40 base::ThreadTaskRunnerHandle::Get(), | 45 base::ThreadTaskRunnerHandle::Get(), |
| 41 base::Bind( | 46 base::Bind( |
| 42 &TestThroughputAnalyzer::OnNewThroughputObservationAvailable, | 47 &TestThroughputAnalyzer::OnNewThroughputObservationAvailable, |
| 43 base::Unretained(this)), | 48 base::Unretained(this)), |
| 44 false, | 49 false, |
| 45 false), | 50 false, |
| 51 base::MakeUnique<BoundTestNetLog>()->bound()), |
| 46 throughput_observations_received_(0), | 52 throughput_observations_received_(0), |
| 47 bits_received_(0) {} | 53 bits_received_(0) {} |
| 48 | 54 |
| 49 ~TestThroughputAnalyzer() override {} | 55 ~TestThroughputAnalyzer() override {} |
| 50 | 56 |
| 51 int32_t throughput_observations_received() const { | 57 int32_t throughput_observations_received() const { |
| 52 return throughput_observations_received_; | 58 return throughput_observations_received_; |
| 53 } | 59 } |
| 54 | 60 |
| 55 void OnNewThroughputObservationAvailable(int32_t downstream_kbps) { | 61 void OnNewThroughputObservationAvailable(int32_t downstream_kbps) { |
| 56 throughput_observations_received_++; | 62 throughput_observations_received_++; |
| 57 } | 63 } |
| 58 | 64 |
| 59 int64_t GetBitsReceived() const override { return bits_received_; } | 65 int64_t GetBitsReceived() const override { return bits_received_; } |
| 60 | 66 |
| 61 void IncrementBitsReceived(int64_t additional_bits_received) { | 67 void IncrementBitsReceived(int64_t additional_bits_received) { |
| 62 bits_received_ += additional_bits_received; | 68 bits_received_ += additional_bits_received; |
| 63 } | 69 } |
| 64 | 70 |
| 71 // Uses a mock resolver to force example.com to resolve to a public IP |
| 72 // address. |
| 73 void AddIPAddressResolution(TestURLRequestContext* context) { |
| 74 scoped_refptr<net::RuleBasedHostResolverProc> rules( |
| 75 new net::RuleBasedHostResolverProc(nullptr)); |
| 76 // example1.com resolves to a public IP address. |
| 77 rules->AddRule("example.com", "27.0.0.3"); |
| 78 mock_host_resolver_.set_rules(rules.get()); |
| 79 context->set_host_resolver(&mock_host_resolver_); |
| 80 } |
| 81 |
| 65 using internal::ThroughputAnalyzer::disable_throughput_measurements; | 82 using internal::ThroughputAnalyzer::disable_throughput_measurements; |
| 66 | 83 |
| 67 private: | 84 private: |
| 68 int throughput_observations_received_; | 85 int throughput_observations_received_; |
| 69 | 86 |
| 70 int64_t bits_received_; | 87 int64_t bits_received_; |
| 71 | 88 |
| 89 MockCachingHostResolver mock_host_resolver_; |
| 90 |
| 72 DISALLOW_COPY_AND_ASSIGN(TestThroughputAnalyzer); | 91 DISALLOW_COPY_AND_ASSIGN(TestThroughputAnalyzer); |
| 73 }; | 92 }; |
| 74 | 93 |
| 75 TEST(ThroughputAnalyzerTest, MaximumRequests) { | 94 TEST(ThroughputAnalyzerTest, MaximumRequests) { |
| 76 const struct { | 95 const struct { |
| 77 bool use_local_requests; | 96 bool use_local_requests; |
| 78 } tests[] = {{ | 97 } tests[] = {{ |
| 79 false, | 98 false, |
| 80 }, | 99 }, |
| 81 { | 100 { |
| 82 true, | 101 true, |
| 83 }}; | 102 }}; |
| 84 | 103 |
| 85 for (const auto& test : tests) { | 104 for (const auto& test : tests) { |
| 86 std::map<std::string, std::string> variation_params; | 105 std::map<std::string, std::string> variation_params; |
| 87 NetworkQualityEstimatorParams params(variation_params); | 106 NetworkQualityEstimatorParams params(variation_params); |
| 88 TestThroughputAnalyzer throughput_analyzer(¶ms); | 107 TestThroughputAnalyzer throughput_analyzer(¶ms); |
| 89 | 108 |
| 90 TestDelegate test_delegate; | 109 TestDelegate test_delegate; |
| 91 TestURLRequestContext context; | 110 TestURLRequestContext context; |
| 111 throughput_analyzer.AddIPAddressResolution(&context); |
| 92 | 112 |
| 93 ASSERT_FALSE(throughput_analyzer.disable_throughput_measurements()); | 113 ASSERT_FALSE(throughput_analyzer.disable_throughput_measurements()); |
| 94 std::deque<std::unique_ptr<URLRequest>> requests; | 114 std::deque<std::unique_ptr<URLRequest>> requests; |
| 95 | 115 |
| 96 // Start more requests than the maximum number of requests that can be held | 116 // Start more requests than the maximum number of requests that can be held |
| 97 // in the memory. | 117 // in the memory. |
| 98 const std::string url = test.use_local_requests | 118 const std::string url = test.use_local_requests |
| 99 ? "http://127.0.0.1/test.html" | 119 ? "http://127.0.0.1/test.html" |
| 100 : "http://example.com/test.html"; | 120 : "http://example.com/test.html"; |
| 121 |
| 122 EXPECT_EQ(test.use_local_requests, |
| 123 nqe::internal::IsPrivateHost( |
| 124 context.host_resolver(), |
| 125 HostPortPair(GURL(url).host(), GURL(url).EffectiveIntPort()), |
| 126 base::MakeUnique<BoundTestNetLog>()->bound())); |
| 101 for (size_t i = 0; i < 1000; ++i) { | 127 for (size_t i = 0; i < 1000; ++i) { |
| 102 std::unique_ptr<URLRequest> request( | 128 std::unique_ptr<URLRequest> request( |
| 103 context.CreateRequest(GURL(url), DEFAULT_PRIORITY, &test_delegate, | 129 context.CreateRequest(GURL(url), DEFAULT_PRIORITY, &test_delegate, |
| 104 TRAFFIC_ANNOTATION_FOR_TESTS)); | 130 TRAFFIC_ANNOTATION_FOR_TESTS)); |
| 105 ASSERT_EQ(test.use_local_requests, IsLocalhost(request->url().host())); | |
| 106 | |
| 107 throughput_analyzer.NotifyStartTransaction(*(request.get())); | 131 throughput_analyzer.NotifyStartTransaction(*(request.get())); |
| 108 requests.push_back(std::move(request)); | 132 requests.push_back(std::move(request)); |
| 109 } | 133 } |
| 110 // Too many local requests should cause the |throughput_analyzer| to disable | 134 // Too many local requests should cause the |throughput_analyzer| to disable |
| 111 // throughput measurements. | 135 // throughput measurements. |
| 112 EXPECT_EQ(test.use_local_requests, | 136 EXPECT_NE(test.use_local_requests, |
| 113 throughput_analyzer.disable_throughput_measurements()); | 137 throughput_analyzer.IsCurrentlyTrackingThroughput()); |
| 114 } | 138 } |
| 115 } | 139 } |
| 116 | 140 |
| 117 // Tests if the throughput observation is taken correctly when local and network | 141 // Tests if the throughput observation is taken correctly when local and network |
| 118 // requests overlap. | 142 // requests overlap. |
| 119 TEST(ThroughputAnalyzerTest, TestThroughputWithMultipleRequestsOverlap) { | 143 TEST(ThroughputAnalyzerTest, TestThroughputWithMultipleRequestsOverlap) { |
| 120 static const struct { | 144 static const struct { |
| 121 bool start_local_request; | 145 bool start_local_request; |
| 122 bool local_request_completes_first; | 146 bool local_request_completes_first; |
| 123 bool expect_throughput_observation; | 147 bool expect_throughput_observation; |
| (...skipping 10 matching lines...) Expand all Loading... |
| 134 }; | 158 }; |
| 135 | 159 |
| 136 for (const auto& test : tests) { | 160 for (const auto& test : tests) { |
| 137 // Localhost requests are not allowed for estimation purposes. | 161 // Localhost requests are not allowed for estimation purposes. |
| 138 std::map<std::string, std::string> variation_params; | 162 std::map<std::string, std::string> variation_params; |
| 139 NetworkQualityEstimatorParams params(variation_params); | 163 NetworkQualityEstimatorParams params(variation_params); |
| 140 TestThroughputAnalyzer throughput_analyzer(¶ms); | 164 TestThroughputAnalyzer throughput_analyzer(¶ms); |
| 141 | 165 |
| 142 TestDelegate test_delegate; | 166 TestDelegate test_delegate; |
| 143 TestURLRequestContext context; | 167 TestURLRequestContext context; |
| 168 throughput_analyzer.AddIPAddressResolution(&context); |
| 144 | 169 |
| 145 std::unique_ptr<URLRequest> request_local; | 170 std::unique_ptr<URLRequest> request_local; |
| 146 | 171 |
| 147 std::unique_ptr<URLRequest> request_not_local(context.CreateRequest( | 172 std::unique_ptr<URLRequest> request_not_local(context.CreateRequest( |
| 148 GURL("http://example.com/echo.html"), DEFAULT_PRIORITY, &test_delegate, | 173 GURL("http://example.com/echo.html"), DEFAULT_PRIORITY, &test_delegate, |
| 149 TRAFFIC_ANNOTATION_FOR_TESTS)); | 174 TRAFFIC_ANNOTATION_FOR_TESTS)); |
| 150 request_not_local->Start(); | 175 request_not_local->Start(); |
| 151 | 176 |
| 152 if (test.start_local_request) { | 177 if (test.start_local_request) { |
| 153 request_local = context.CreateRequest(GURL("http://localhost/echo.html"), | 178 request_local = context.CreateRequest(GURL("http://127.0.0.1/echo.html"), |
| 154 DEFAULT_PRIORITY, &test_delegate, | 179 DEFAULT_PRIORITY, &test_delegate, |
| 155 TRAFFIC_ANNOTATION_FOR_TESTS); | 180 TRAFFIC_ANNOTATION_FOR_TESTS); |
| 156 request_local->Start(); | 181 request_local->Start(); |
| 157 } | 182 } |
| 158 | 183 |
| 159 base::RunLoop().Run(); | 184 base::RunLoop().Run(); |
| 160 | 185 |
| 161 EXPECT_EQ(0, throughput_analyzer.throughput_observations_received()); | 186 EXPECT_EQ(0, throughput_analyzer.throughput_observations_received()); |
| 162 | 187 |
| 163 // If |test.start_local_request| is true, then |request_local| starts | 188 // If |test.start_local_request| is true, then |request_local| starts |
| (...skipping 58 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 222 | 247 |
| 223 for (const auto& test : tests) { | 248 for (const auto& test : tests) { |
| 224 // Localhost requests are not allowed for estimation purposes. | 249 // Localhost requests are not allowed for estimation purposes. |
| 225 std::map<std::string, std::string> variation_params; | 250 std::map<std::string, std::string> variation_params; |
| 226 variation_params["throughput_min_requests_in_flight"] = | 251 variation_params["throughput_min_requests_in_flight"] = |
| 227 base::IntToString(test.throughput_min_requests_in_flight); | 252 base::IntToString(test.throughput_min_requests_in_flight); |
| 228 NetworkQualityEstimatorParams params(variation_params); | 253 NetworkQualityEstimatorParams params(variation_params); |
| 229 TestThroughputAnalyzer throughput_analyzer(¶ms); | 254 TestThroughputAnalyzer throughput_analyzer(¶ms); |
| 230 TestDelegate test_delegate; | 255 TestDelegate test_delegate; |
| 231 TestURLRequestContext context; | 256 TestURLRequestContext context; |
| 257 throughput_analyzer.AddIPAddressResolution(&context); |
| 232 | 258 |
| 233 EXPECT_EQ(0, throughput_analyzer.throughput_observations_received()); | 259 EXPECT_EQ(0, throughput_analyzer.throughput_observations_received()); |
| 234 | 260 |
| 235 std::vector<std::unique_ptr<URLRequest>> requests_in_flight; | 261 std::vector<std::unique_ptr<URLRequest>> requests_in_flight; |
| 236 | 262 |
| 237 for (size_t i = 0; i < test.number_requests_in_flight; ++i) { | 263 for (size_t i = 0; i < test.number_requests_in_flight; ++i) { |
| 238 std::unique_ptr<URLRequest> request_network_1 = context.CreateRequest( | 264 std::unique_ptr<URLRequest> request_network_1 = context.CreateRequest( |
| 239 GURL("http://example.com/echo.html"), DEFAULT_PRIORITY, | 265 GURL("http://example.com/echo.html"), DEFAULT_PRIORITY, |
| 240 &test_delegate, TRAFFIC_ANNOTATION_FOR_TESTS); | 266 &test_delegate, TRAFFIC_ANNOTATION_FOR_TESTS); |
| 241 requests_in_flight.push_back(std::move(request_network_1)); | 267 requests_in_flight.push_back(std::move(request_network_1)); |
| (...skipping 32 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 274 // Tests if the throughput observation is taken correctly when the start and end | 300 // Tests if the throughput observation is taken correctly when the start and end |
| 275 // of network requests overlap, and the minimum number of in flight requests | 301 // of network requests overlap, and the minimum number of in flight requests |
| 276 // when taking an observation is more than 1. | 302 // when taking an observation is more than 1. |
| 277 TEST(ThroughputAnalyzerTest, TestThroughputWithMultipleNetworkRequests) { | 303 TEST(ThroughputAnalyzerTest, TestThroughputWithMultipleNetworkRequests) { |
| 278 std::map<std::string, std::string> variation_params; | 304 std::map<std::string, std::string> variation_params; |
| 279 variation_params["throughput_min_requests_in_flight"] = "3"; | 305 variation_params["throughput_min_requests_in_flight"] = "3"; |
| 280 NetworkQualityEstimatorParams params(variation_params); | 306 NetworkQualityEstimatorParams params(variation_params); |
| 281 TestThroughputAnalyzer throughput_analyzer(¶ms); | 307 TestThroughputAnalyzer throughput_analyzer(¶ms); |
| 282 TestDelegate test_delegate; | 308 TestDelegate test_delegate; |
| 283 TestURLRequestContext context; | 309 TestURLRequestContext context; |
| 310 throughput_analyzer.AddIPAddressResolution(&context); |
| 284 | 311 |
| 285 EXPECT_EQ(0, throughput_analyzer.throughput_observations_received()); | 312 EXPECT_EQ(0, throughput_analyzer.throughput_observations_received()); |
| 286 | 313 |
| 287 std::unique_ptr<URLRequest> request_1 = context.CreateRequest( | 314 std::unique_ptr<URLRequest> request_1 = context.CreateRequest( |
| 288 GURL("http://example.com/echo.html"), DEFAULT_PRIORITY, &test_delegate, | 315 GURL("http://example.com/echo.html"), DEFAULT_PRIORITY, &test_delegate, |
| 289 TRAFFIC_ANNOTATION_FOR_TESTS); | 316 TRAFFIC_ANNOTATION_FOR_TESTS); |
| 290 std::unique_ptr<URLRequest> request_2 = context.CreateRequest( | 317 std::unique_ptr<URLRequest> request_2 = context.CreateRequest( |
| 291 GURL("http://example.com/echo.html"), DEFAULT_PRIORITY, &test_delegate, | 318 GURL("http://example.com/echo.html"), DEFAULT_PRIORITY, &test_delegate, |
| 292 TRAFFIC_ANNOTATION_FOR_TESTS); | 319 TRAFFIC_ANNOTATION_FOR_TESTS); |
| 293 std::unique_ptr<URLRequest> request_3 = context.CreateRequest( | 320 std::unique_ptr<URLRequest> request_3 = context.CreateRequest( |
| (...skipping 42 matching lines...) Expand 10 before | Expand all | Expand 10 after Loading... |
| 336 throughput_analyzer.NotifyRequestCompleted(*(request_3.get())); | 363 throughput_analyzer.NotifyRequestCompleted(*(request_3.get())); |
| 337 throughput_analyzer.NotifyRequestCompleted(*(request_4.get())); | 364 throughput_analyzer.NotifyRequestCompleted(*(request_4.get())); |
| 338 EXPECT_EQ(1, throughput_analyzer.throughput_observations_received()); | 365 EXPECT_EQ(1, throughput_analyzer.throughput_observations_received()); |
| 339 } | 366 } |
| 340 | 367 |
| 341 } // namespace | 368 } // namespace |
| 342 | 369 |
| 343 } // namespace nqe | 370 } // namespace nqe |
| 344 | 371 |
| 345 } // namespace net | 372 } // namespace net |
| OLD | NEW |