Chromium Code Reviews| 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 // Use a mock resolver to force example.com to resolve to a public IP address. | |
|
bengr
2017/06/18 20:42:59
nit: Use -> Uses
tbansal1
2017/06/19 05:50:41
Done.
| |
| 72 void AddIPAddressResolution(TestURLRequestContext* context) { | |
| 73 scoped_refptr<net::RuleBasedHostResolverProc> rules( | |
| 74 new net::RuleBasedHostResolverProc(nullptr)); | |
| 75 // example1.com resolves to a public IP address. | |
| 76 rules->AddRule("example.com", "27.0.0.3"); | |
| 77 mock_host_resolver_.set_rules(rules.get()); | |
| 78 context->set_host_resolver(&mock_host_resolver_); | |
| 79 } | |
| 80 | |
| 65 using internal::ThroughputAnalyzer::disable_throughput_measurements; | 81 using internal::ThroughputAnalyzer::disable_throughput_measurements; |
| 66 | 82 |
| 67 private: | 83 private: |
| 68 int throughput_observations_received_; | 84 int throughput_observations_received_; |
| 69 | 85 |
| 70 int64_t bits_received_; | 86 int64_t bits_received_; |
| 71 | 87 |
| 88 MockCachingHostResolver mock_host_resolver_; | |
| 89 | |
| 72 DISALLOW_COPY_AND_ASSIGN(TestThroughputAnalyzer); | 90 DISALLOW_COPY_AND_ASSIGN(TestThroughputAnalyzer); |
| 73 }; | 91 }; |
| 74 | 92 |
| 75 TEST(ThroughputAnalyzerTest, MaximumRequests) { | 93 TEST(ThroughputAnalyzerTest, MaximumRequests) { |
| 76 const struct { | 94 const struct { |
| 77 bool use_local_requests; | 95 bool use_local_requests; |
| 78 } tests[] = {{ | 96 } tests[] = {{ |
| 79 false, | 97 false, |
| 80 }, | 98 }, |
| 81 { | 99 { |
| 82 true, | 100 true, |
| 83 }}; | 101 }}; |
| 84 | 102 |
| 85 for (const auto& test : tests) { | 103 for (const auto& test : tests) { |
| 86 std::map<std::string, std::string> variation_params; | 104 std::map<std::string, std::string> variation_params; |
| 87 NetworkQualityEstimatorParams params(variation_params); | 105 NetworkQualityEstimatorParams params(variation_params); |
| 88 TestThroughputAnalyzer throughput_analyzer(¶ms); | 106 TestThroughputAnalyzer throughput_analyzer(¶ms); |
| 89 | 107 |
| 90 TestDelegate test_delegate; | 108 TestDelegate test_delegate; |
| 91 TestURLRequestContext context; | 109 TestURLRequestContext context; |
| 110 throughput_analyzer.AddIPAddressResolution(&context); | |
| 92 | 111 |
| 93 ASSERT_FALSE(throughput_analyzer.disable_throughput_measurements()); | 112 ASSERT_FALSE(throughput_analyzer.disable_throughput_measurements()); |
| 94 std::deque<std::unique_ptr<URLRequest>> requests; | 113 std::deque<std::unique_ptr<URLRequest>> requests; |
| 95 | 114 |
| 96 // Start more requests than the maximum number of requests that can be held | 115 // Start more requests than the maximum number of requests that can be held |
| 97 // in the memory. | 116 // in the memory. |
| 98 const std::string url = test.use_local_requests | 117 const std::string url = test.use_local_requests |
| 99 ? "http://127.0.0.1/test.html" | 118 ? "http://127.0.0.1/test.html" |
| 100 : "http://example.com/test.html"; | 119 : "http://example.com/test.html"; |
| 120 | |
| 121 EXPECT_EQ(test.use_local_requests, | |
| 122 nqe::internal::IsPrivateHost( | |
| 123 context.host_resolver(), | |
| 124 HostPortPair(GURL(url).host(), GURL(url).EffectiveIntPort()), | |
| 125 base::MakeUnique<BoundTestNetLog>()->bound())); | |
| 101 for (size_t i = 0; i < 1000; ++i) { | 126 for (size_t i = 0; i < 1000; ++i) { |
| 102 std::unique_ptr<URLRequest> request( | 127 std::unique_ptr<URLRequest> request( |
| 103 context.CreateRequest(GURL(url), DEFAULT_PRIORITY, &test_delegate, | 128 context.CreateRequest(GURL(url), DEFAULT_PRIORITY, &test_delegate, |
| 104 TRAFFIC_ANNOTATION_FOR_TESTS)); | 129 TRAFFIC_ANNOTATION_FOR_TESTS)); |
| 105 ASSERT_EQ(test.use_local_requests, IsLocalhost(request->url().host())); | |
| 106 | |
| 107 throughput_analyzer.NotifyStartTransaction(*(request.get())); | 130 throughput_analyzer.NotifyStartTransaction(*(request.get())); |
| 108 requests.push_back(std::move(request)); | 131 requests.push_back(std::move(request)); |
| 109 } | 132 } |
| 110 // Too many local requests should cause the |throughput_analyzer| to disable | 133 // Too many local requests should cause the |throughput_analyzer| to disable |
| 111 // throughput measurements. | 134 // throughput measurements. |
| 112 EXPECT_EQ(test.use_local_requests, | 135 EXPECT_NE(test.use_local_requests, |
| 113 throughput_analyzer.disable_throughput_measurements()); | 136 throughput_analyzer.IsCurrentlyTrackingThroughput()); |
| 114 } | 137 } |
| 115 } | 138 } |
| 116 | 139 |
| 117 // Tests if the throughput observation is taken correctly when local and network | 140 // Tests if the throughput observation is taken correctly when local and network |
| 118 // requests overlap. | 141 // requests overlap. |
| 119 TEST(ThroughputAnalyzerTest, TestThroughputWithMultipleRequestsOverlap) { | 142 TEST(ThroughputAnalyzerTest, TestThroughputWithMultipleRequestsOverlap) { |
| 120 static const struct { | 143 static const struct { |
| 121 bool start_local_request; | 144 bool start_local_request; |
| 122 bool local_request_completes_first; | 145 bool local_request_completes_first; |
| 123 bool expect_throughput_observation; | 146 bool expect_throughput_observation; |
| (...skipping 10 matching lines...) Expand all Loading... | |
| 134 }; | 157 }; |
| 135 | 158 |
| 136 for (const auto& test : tests) { | 159 for (const auto& test : tests) { |
| 137 // Localhost requests are not allowed for estimation purposes. | 160 // Localhost requests are not allowed for estimation purposes. |
| 138 std::map<std::string, std::string> variation_params; | 161 std::map<std::string, std::string> variation_params; |
| 139 NetworkQualityEstimatorParams params(variation_params); | 162 NetworkQualityEstimatorParams params(variation_params); |
| 140 TestThroughputAnalyzer throughput_analyzer(¶ms); | 163 TestThroughputAnalyzer throughput_analyzer(¶ms); |
| 141 | 164 |
| 142 TestDelegate test_delegate; | 165 TestDelegate test_delegate; |
| 143 TestURLRequestContext context; | 166 TestURLRequestContext context; |
| 167 throughput_analyzer.AddIPAddressResolution(&context); | |
| 144 | 168 |
| 145 std::unique_ptr<URLRequest> request_local; | 169 std::unique_ptr<URLRequest> request_local; |
| 146 | 170 |
| 147 std::unique_ptr<URLRequest> request_not_local(context.CreateRequest( | 171 std::unique_ptr<URLRequest> request_not_local(context.CreateRequest( |
| 148 GURL("http://example.com/echo.html"), DEFAULT_PRIORITY, &test_delegate, | 172 GURL("http://example.com/echo.html"), DEFAULT_PRIORITY, &test_delegate, |
| 149 TRAFFIC_ANNOTATION_FOR_TESTS)); | 173 TRAFFIC_ANNOTATION_FOR_TESTS)); |
| 150 request_not_local->Start(); | 174 request_not_local->Start(); |
| 151 | 175 |
| 152 if (test.start_local_request) { | 176 if (test.start_local_request) { |
| 153 request_local = context.CreateRequest(GURL("http://localhost/echo.html"), | 177 request_local = context.CreateRequest(GURL("http://127.0.0.1/echo.html"), |
| 154 DEFAULT_PRIORITY, &test_delegate, | 178 DEFAULT_PRIORITY, &test_delegate, |
| 155 TRAFFIC_ANNOTATION_FOR_TESTS); | 179 TRAFFIC_ANNOTATION_FOR_TESTS); |
| 156 request_local->Start(); | 180 request_local->Start(); |
| 157 } | 181 } |
| 158 | 182 |
| 159 base::RunLoop().Run(); | 183 base::RunLoop().Run(); |
| 160 | 184 |
| 161 EXPECT_EQ(0, throughput_analyzer.throughput_observations_received()); | 185 EXPECT_EQ(0, throughput_analyzer.throughput_observations_received()); |
| 162 | 186 |
| 163 // If |test.start_local_request| is true, then |request_local| starts | 187 // 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 | 246 |
| 223 for (const auto& test : tests) { | 247 for (const auto& test : tests) { |
| 224 // Localhost requests are not allowed for estimation purposes. | 248 // Localhost requests are not allowed for estimation purposes. |
| 225 std::map<std::string, std::string> variation_params; | 249 std::map<std::string, std::string> variation_params; |
| 226 variation_params["throughput_min_requests_in_flight"] = | 250 variation_params["throughput_min_requests_in_flight"] = |
| 227 base::IntToString(test.throughput_min_requests_in_flight); | 251 base::IntToString(test.throughput_min_requests_in_flight); |
| 228 NetworkQualityEstimatorParams params(variation_params); | 252 NetworkQualityEstimatorParams params(variation_params); |
| 229 TestThroughputAnalyzer throughput_analyzer(¶ms); | 253 TestThroughputAnalyzer throughput_analyzer(¶ms); |
| 230 TestDelegate test_delegate; | 254 TestDelegate test_delegate; |
| 231 TestURLRequestContext context; | 255 TestURLRequestContext context; |
| 256 throughput_analyzer.AddIPAddressResolution(&context); | |
| 232 | 257 |
| 233 EXPECT_EQ(0, throughput_analyzer.throughput_observations_received()); | 258 EXPECT_EQ(0, throughput_analyzer.throughput_observations_received()); |
| 234 | 259 |
| 235 std::vector<std::unique_ptr<URLRequest>> requests_in_flight; | 260 std::vector<std::unique_ptr<URLRequest>> requests_in_flight; |
| 236 | 261 |
| 237 for (size_t i = 0; i < test.number_requests_in_flight; ++i) { | 262 for (size_t i = 0; i < test.number_requests_in_flight; ++i) { |
| 238 std::unique_ptr<URLRequest> request_network_1 = context.CreateRequest( | 263 std::unique_ptr<URLRequest> request_network_1 = context.CreateRequest( |
| 239 GURL("http://example.com/echo.html"), DEFAULT_PRIORITY, | 264 GURL("http://example.com/echo.html"), DEFAULT_PRIORITY, |
| 240 &test_delegate, TRAFFIC_ANNOTATION_FOR_TESTS); | 265 &test_delegate, TRAFFIC_ANNOTATION_FOR_TESTS); |
| 241 requests_in_flight.push_back(std::move(request_network_1)); | 266 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 | 299 // 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 | 300 // of network requests overlap, and the minimum number of in flight requests |
| 276 // when taking an observation is more than 1. | 301 // when taking an observation is more than 1. |
| 277 TEST(ThroughputAnalyzerTest, TestThroughputWithMultipleNetworkRequests) { | 302 TEST(ThroughputAnalyzerTest, TestThroughputWithMultipleNetworkRequests) { |
| 278 std::map<std::string, std::string> variation_params; | 303 std::map<std::string, std::string> variation_params; |
| 279 variation_params["throughput_min_requests_in_flight"] = "3"; | 304 variation_params["throughput_min_requests_in_flight"] = "3"; |
| 280 NetworkQualityEstimatorParams params(variation_params); | 305 NetworkQualityEstimatorParams params(variation_params); |
| 281 TestThroughputAnalyzer throughput_analyzer(¶ms); | 306 TestThroughputAnalyzer throughput_analyzer(¶ms); |
| 282 TestDelegate test_delegate; | 307 TestDelegate test_delegate; |
| 283 TestURLRequestContext context; | 308 TestURLRequestContext context; |
| 309 throughput_analyzer.AddIPAddressResolution(&context); | |
| 284 | 310 |
| 285 EXPECT_EQ(0, throughput_analyzer.throughput_observations_received()); | 311 EXPECT_EQ(0, throughput_analyzer.throughput_observations_received()); |
| 286 | 312 |
| 287 std::unique_ptr<URLRequest> request_1 = context.CreateRequest( | 313 std::unique_ptr<URLRequest> request_1 = context.CreateRequest( |
| 288 GURL("http://example.com/echo.html"), DEFAULT_PRIORITY, &test_delegate, | 314 GURL("http://example.com/echo.html"), DEFAULT_PRIORITY, &test_delegate, |
| 289 TRAFFIC_ANNOTATION_FOR_TESTS); | 315 TRAFFIC_ANNOTATION_FOR_TESTS); |
| 290 std::unique_ptr<URLRequest> request_2 = context.CreateRequest( | 316 std::unique_ptr<URLRequest> request_2 = context.CreateRequest( |
| 291 GURL("http://example.com/echo.html"), DEFAULT_PRIORITY, &test_delegate, | 317 GURL("http://example.com/echo.html"), DEFAULT_PRIORITY, &test_delegate, |
| 292 TRAFFIC_ANNOTATION_FOR_TESTS); | 318 TRAFFIC_ANNOTATION_FOR_TESTS); |
| 293 std::unique_ptr<URLRequest> request_3 = context.CreateRequest( | 319 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())); | 362 throughput_analyzer.NotifyRequestCompleted(*(request_3.get())); |
| 337 throughput_analyzer.NotifyRequestCompleted(*(request_4.get())); | 363 throughput_analyzer.NotifyRequestCompleted(*(request_4.get())); |
| 338 EXPECT_EQ(1, throughput_analyzer.throughput_observations_received()); | 364 EXPECT_EQ(1, throughput_analyzer.throughput_observations_received()); |
| 339 } | 365 } |
| 340 | 366 |
| 341 } // namespace | 367 } // namespace |
| 342 | 368 |
| 343 } // namespace nqe | 369 } // namespace nqe |
| 344 | 370 |
| 345 } // namespace net | 371 } // namespace net |
| OLD | NEW |