blob: 1b723170bb4e230c9c7c5791c107a2b31b5d98d7 [file] [log] [blame]
[email protected]a9344092d2013-02-27 00:56:451// Copyright (c) 2012 The Chromium Authors. All rights reserved.
2// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
4
5#include "content/browser/loader/resource_scheduler.h"
6
Devdeep Ray3d467db2017-07-25 01:06:467#include <map>
avi933295f52017-01-03 19:50:278#include <memory>
Devdeep Ray3d467db2017-07-25 01:06:469#include <set>
10#include <string>
dcheng36b6aec92015-12-26 06:16:3611#include <utility>
avi933295f52017-01-03 19:50:2712#include <vector>
dcheng36b6aec92015-12-26 06:16:3613
robliao79393ffb2016-09-21 18:45:2914#include "base/memory/ptr_util.h"
Josh Karlin5b2b3d32017-08-31 13:08:3815#include "base/memory/ref_counted.h"
jkarlinbf88dc8e2017-02-22 21:40:0316#include "base/metrics/field_trial.h"
17#include "base/metrics/field_trial_param_associator.h"
Devdeep Ray3d467db2017-07-25 01:06:4618#include "base/metrics/field_trial_params.h"
zhenwe0b2af8a2014-08-25 16:07:3019#include "base/run_loop.h"
[email protected]0cb0e55b2013-03-24 04:58:2120#include "base/strings/string_number_conversions.h"
tbansal29fc633862017-06-06 22:50:2321#include "base/test/histogram_tester.h"
jkarlinbf88dc8e2017-02-22 21:40:0322#include "base/test/mock_entropy_provider.h"
jkarlina9d98bd32016-10-19 18:45:4823#include "base/test/scoped_feature_list.h"
Josh Karlin5b2b3d32017-08-31 13:08:3824#include "base/test/test_mock_time_task_runner.h"
[email protected]1a718bd2014-07-30 01:22:2225#include "base/timer/mock_timer.h"
26#include "base/timer/timer.h"
[email protected]0cb0e55b2013-03-24 04:58:2127#include "content/public/browser/resource_context.h"
[email protected]a9344092d2013-02-27 00:56:4528#include "content/public/browser/resource_throttle.h"
zhenwe0b2af8a2014-08-25 16:07:3029#include "content/public/test/mock_render_process_host.h"
30#include "content/public/test/test_browser_context.h"
gab606d46c2016-11-09 23:07:2131#include "content/public/test/test_browser_thread_bundle.h"
aiolos6e7ce492014-10-10 00:48:5332#include "content/test/test_render_view_host_factory.h"
zhenwe0b2af8a2014-08-25 16:07:3033#include "content/test/test_web_contents.h"
[email protected]3ccdeec12013-05-02 16:36:5334#include "net/base/host_port_pair.h"
[email protected]2ca01e52013-10-31 22:05:1935#include "net/base/request_priority.h"
[email protected]3ccdeec12013-05-02 16:36:5336#include "net/http/http_server_properties_impl.h"
Devdeep Ray3d467db2017-07-25 01:06:4637#include "net/nqe/network_quality_estimator_test_util.h"
38#include "net/test/embedded_test_server/embedded_test_server.h"
rhalavatia20efdbc2017-04-20 12:28:2739#include "net/traffic_annotation/network_traffic_annotation_test_helper.h"
[email protected]a9344092d2013-02-27 00:56:4540#include "net/url_request/url_request.h"
41#include "net/url_request/url_request_test_util.h"
tbansal29fc633862017-06-06 22:50:2342#include "testing/gmock/include/gmock/gmock.h"
[email protected]a9344092d2013-02-27 00:56:4543#include "testing/gtest/include/gtest/gtest.h"
mfomitchev3ba450ad2017-04-03 18:20:4044#include "ui/latency/latency_info.h"
zhongyi3d4a55e72016-04-22 20:36:4645#include "url/scheme_host_port.h"
[email protected]a9344092d2013-02-27 00:56:4546
halton.huoe4e45742014-12-08 07:55:4647using std::string;
48
[email protected]a9344092d2013-02-27 00:56:4549namespace content {
50
51namespace {
52
53class TestRequestFactory;
54
55const int kChildId = 30;
56const int kRouteId = 75;
[email protected]312c24f2014-07-15 22:30:5557const int kChildId2 = 43;
58const int kRouteId2 = 67;
59const int kBackgroundChildId = 35;
60const int kBackgroundRouteId = 43;
[email protected]a9344092d2013-02-27 00:56:4561
Josh Karlin40b0fcdb2017-08-28 15:33:5462// Sync below with cc file.
jkarlina9d98bd32016-10-19 18:45:4863const char kPrioritySupportedRequestsDelayable[] =
64 "PrioritySupportedRequestsDelayable";
Josh Karlin40b0fcdb2017-08-28 15:33:5465const char kHeadPrioritySupportedRequestsDelayable[] =
66 "HeadPriorityRequestsDelayable";
jkarlinbf88dc8e2017-02-22 21:40:0367const char kNetworkSchedulerYielding[] = "NetworkSchedulerYielding";
Josh Karlin40b0fcdb2017-08-28 15:33:5468const size_t kMaxNumDelayableRequestsPerHostPerClient = 6;
jkarlinbf88dc8e2017-02-22 21:40:0369
Josh Karlin5b2b3d32017-08-31 13:08:3870void ConfigureYieldFieldTrial(
71 int max_requests_before_yielding,
72 int max_yield_ms,
73 base::test::ScopedFeatureList* scoped_feature_list) {
74 const std::string kTrialName = "TrialName";
75 const std::string kGroupName = "GroupName"; // Value not used
76 const std::string kNetworkSchedulerYielding = "NetworkSchedulerYielding";
77
78 scoped_refptr<base::FieldTrial> trial =
79 base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName);
80
81 std::map<std::string, std::string> params;
82 params["MaxRequestsBeforeYieldingParam"] =
83 base::IntToString(max_requests_before_yielding);
84 params["MaxYieldMs"] = base::IntToString(max_yield_ms);
85 base::FieldTrialParamAssociator::GetInstance()->AssociateFieldTrialParams(
86 kTrialName, kGroupName, params);
87
88 std::unique_ptr<base::FeatureList> feature_list(new base::FeatureList);
89 feature_list->RegisterFieldTrialOverride(
90 kNetworkSchedulerYielding, base::FeatureList::OVERRIDE_ENABLE_FEATURE,
91 trial.get());
92 scoped_feature_list->InitWithFeatureList(std::move(feature_list));
93}
94
tyoshino64fa0922016-12-07 07:40:0995class TestRequest : public ResourceThrottle::Delegate {
[email protected]a9344092d2013-02-27 00:56:4596 public:
dcheng40ce7b382016-04-08 23:46:1397 TestRequest(std::unique_ptr<net::URLRequest> url_request,
98 std::unique_ptr<ResourceThrottle> throttle,
ricea6e001fc2015-08-14 18:25:2999 ResourceScheduler* scheduler)
[email protected]a9344092d2013-02-27 00:56:45100 : started_(false),
dcheng36b6aec92015-12-26 06:16:36101 url_request_(std::move(url_request)),
102 throttle_(std::move(throttle)),
ricea6e001fc2015-08-14 18:25:29103 scheduler_(scheduler) {
tyoshino64fa0922016-12-07 07:40:09104 throttle_->set_delegate_for_testing(this);
[email protected]a9344092d2013-02-27 00:56:45105 }
ricea6e001fc2015-08-14 18:25:29106 ~TestRequest() override {
107 // The URLRequest must still be valid when the ScheduledResourceRequest is
108 // destroyed, so that it can unregister itself.
109 throttle_.reset();
110 }
[email protected]a9344092d2013-02-27 00:56:45111
112 bool started() const { return started_; }
113
114 void Start() {
115 bool deferred = false;
116 throttle_->WillStartRequest(&deferred);
117 started_ = !deferred;
118 }
119
ricea6e001fc2015-08-14 18:25:29120 void ChangePriority(net::RequestPriority new_priority, int intra_priority) {
121 scheduler_->ReprioritizeRequest(url_request_.get(), new_priority,
122 intra_priority);
123 }
124
dchengc2282aa2014-10-21 12:07:58125 void Cancel() override {
[email protected]312c24f2014-07-15 22:30:55126 // Alert the scheduler that the request can be deleted.
ricea6e001fc2015-08-14 18:25:29127 throttle_.reset();
[email protected]312c24f2014-07-15 22:30:55128 }
129
[email protected]0cb0e55b2013-03-24 04:58:21130 const net::URLRequest* url_request() const { return url_request_.get(); }
131
[email protected]a9344092d2013-02-27 00:56:45132 protected:
tyoshino64fa0922016-12-07 07:40:09133 // ResourceThrottle::Delegate interface:
dchengc2282aa2014-10-21 12:07:58134 void CancelWithError(int error_code) override {}
135 void Resume() override { started_ = true; }
[email protected]a9344092d2013-02-27 00:56:45136
137 private:
138 bool started_;
dcheng40ce7b382016-04-08 23:46:13139 std::unique_ptr<net::URLRequest> url_request_;
140 std::unique_ptr<ResourceThrottle> throttle_;
ricea6e001fc2015-08-14 18:25:29141 ResourceScheduler* scheduler_;
[email protected]a9344092d2013-02-27 00:56:45142};
143
144class CancelingTestRequest : public TestRequest {
145 public:
dcheng40ce7b382016-04-08 23:46:13146 CancelingTestRequest(std::unique_ptr<net::URLRequest> url_request,
147 std::unique_ptr<ResourceThrottle> throttle,
ricea6e001fc2015-08-14 18:25:29148 ResourceScheduler* scheduler)
dcheng36b6aec92015-12-26 06:16:36149 : TestRequest(std::move(url_request), std::move(throttle), scheduler) {}
[email protected]a9344092d2013-02-27 00:56:45150
dcheng40ce7b382016-04-08 23:46:13151 void set_request_to_cancel(std::unique_ptr<TestRequest> request_to_cancel) {
dcheng36b6aec92015-12-26 06:16:36152 request_to_cancel_ = std::move(request_to_cancel);
[email protected]a9344092d2013-02-27 00:56:45153 }
154
155 private:
dchengc2282aa2014-10-21 12:07:58156 void Resume() override {
[email protected]a9344092d2013-02-27 00:56:45157 TestRequest::Resume();
158 request_to_cancel_.reset();
159 }
160
dcheng40ce7b382016-04-08 23:46:13161 std::unique_ptr<TestRequest> request_to_cancel_;
[email protected]a9344092d2013-02-27 00:56:45162};
163
[email protected]0cb0e55b2013-03-24 04:58:21164class FakeResourceContext : public ResourceContext {
165 private:
Ivan Kotenkov2c0d2bb32017-11-01 15:41:28166 net::HostResolver* GetHostResolver() override { return nullptr; }
167 net::URLRequestContext* GetRequestContext() override { return nullptr; }
[email protected]0cb0e55b2013-03-24 04:58:21168};
169
[email protected]a9344092d2013-02-27 00:56:45170class ResourceSchedulerTest : public testing::Test {
171 protected:
Devdeep Ray3d467db2017-07-25 01:06:46172 ResourceSchedulerTest() : field_trial_list_(nullptr) {
rdsmith34d4a6c2015-06-24 19:38:55173 InitializeScheduler();
bnc525e175a2016-06-20 12:36:40174 context_.set_http_server_properties(&http_server_properties_);
Devdeep Ray3d467db2017-07-25 01:06:46175 context_.set_network_quality_estimator(&network_quality_estimator_);
[email protected]a9344092d2013-02-27 00:56:45176 }
177
dchengfa85b152014-10-28 01:13:42178 ~ResourceSchedulerTest() override {
rdsmith34d4a6c2015-06-24 19:38:55179 CleanupScheduler();
180 }
181
182 // Done separately from construction to allow for modification of command
183 // line flags in tests.
Alex Clarke9155a342017-09-15 10:56:59184 void InitializeScheduler(bool enabled = true) {
rdsmith34d4a6c2015-06-24 19:38:55185 CleanupScheduler();
186
187 // Destroys previous scheduler, also destroys any previously created
188 // mock_timer_.
Alex Clarke9155a342017-09-15 10:56:59189 scheduler_.reset(new ResourceScheduler(enabled));
rdsmith34d4a6c2015-06-24 19:38:55190
Devdeep Ray3d467db2017-07-25 01:06:46191 scheduler_->OnClientCreated(kChildId, kRouteId,
192 &network_quality_estimator_);
193 scheduler_->OnClientCreated(kBackgroundChildId, kBackgroundRouteId,
194 &network_quality_estimator_);
rdsmith34d4a6c2015-06-24 19:38:55195 }
196
197 void CleanupScheduler() {
198 if (scheduler_) {
199 scheduler_->OnClientDeleted(kChildId, kRouteId);
200 scheduler_->OnClientDeleted(kBackgroundChildId, kBackgroundRouteId);
201 }
202 }
203
dcheng40ce7b382016-04-08 23:46:13204 std::unique_ptr<net::URLRequest> NewURLRequestWithChildAndRoute(
[email protected]0cb0e55b2013-03-24 04:58:21205 const char* url,
206 net::RequestPriority priority,
[email protected]312c24f2014-07-15 22:30:55207 int child_id,
ricea6e001fc2015-08-14 18:25:29208 int route_id) {
rhalavatia20efdbc2017-04-20 12:28:27209 std::unique_ptr<net::URLRequest> url_request(context_.CreateRequest(
Devdeep Ray3d467db2017-07-25 01:06:46210 GURL(url), priority, nullptr, TRAFFIC_ANNOTATION_FOR_TESTS));
dcheng36b6aec92015-12-26 06:16:36211 return url_request;
[email protected]a9344092d2013-02-27 00:56:45212 }
213
dcheng40ce7b382016-04-08 23:46:13214 std::unique_ptr<net::URLRequest> NewURLRequest(
215 const char* url,
216 net::RequestPriority priority) {
ricea6e001fc2015-08-14 18:25:29217 return NewURLRequestWithChildAndRoute(url, priority, kChildId, kRouteId);
[email protected]0cb0e55b2013-03-24 04:58:21218 }
219
avi933295f52017-01-03 19:50:27220 std::unique_ptr<TestRequest> NewRequestWithRoute(
221 const char* url,
222 net::RequestPriority priority,
223 int route_id) {
riceaea679d42015-08-13 23:45:05224 return NewRequestWithChildAndRoute(url, priority, kChildId, route_id);
[email protected]312c24f2014-07-15 22:30:55225 }
226
avi933295f52017-01-03 19:50:27227 std::unique_ptr<TestRequest> NewRequestWithChildAndRoute(
228 const char* url,
229 net::RequestPriority priority,
230 int child_id,
231 int route_id) {
[email protected]312c24f2014-07-15 22:30:55232 return GetNewTestRequest(url, priority, child_id, route_id, true);
233 }
234
avi933295f52017-01-03 19:50:27235 std::unique_ptr<TestRequest> NewRequest(const char* url,
236 net::RequestPriority priority) {
[email protected]312c24f2014-07-15 22:30:55237 return NewRequestWithChildAndRoute(url, priority, kChildId, kRouteId);
238 }
239
avi933295f52017-01-03 19:50:27240 std::unique_ptr<TestRequest> NewBackgroundRequest(
241 const char* url,
242 net::RequestPriority priority) {
[email protected]312c24f2014-07-15 22:30:55243 return NewRequestWithChildAndRoute(
244 url, priority, kBackgroundChildId, kBackgroundRouteId);
245 }
246
avi933295f52017-01-03 19:50:27247 std::unique_ptr<TestRequest> NewSyncRequest(const char* url,
248 net::RequestPriority priority) {
[email protected]312c24f2014-07-15 22:30:55249 return NewSyncRequestWithChildAndRoute(url, priority, kChildId, kRouteId);
250 }
251
avi933295f52017-01-03 19:50:27252 std::unique_ptr<TestRequest> NewBackgroundSyncRequest(
253 const char* url,
254 net::RequestPriority priority) {
[email protected]312c24f2014-07-15 22:30:55255 return NewSyncRequestWithChildAndRoute(
256 url, priority, kBackgroundChildId, kBackgroundRouteId);
257 }
258
avi933295f52017-01-03 19:50:27259 std::unique_ptr<TestRequest> NewSyncRequestWithChildAndRoute(
260 const char* url,
261 net::RequestPriority priority,
262 int child_id,
263 int route_id) {
[email protected]312c24f2014-07-15 22:30:55264 return GetNewTestRequest(url, priority, child_id, route_id, false);
265 }
266
avi933295f52017-01-03 19:50:27267 std::unique_ptr<TestRequest> GetNewTestRequest(const char* url,
268 net::RequestPriority priority,
269 int child_id,
270 int route_id,
271 bool is_async) {
dcheng40ce7b382016-04-08 23:46:13272 std::unique_ptr<net::URLRequest> url_request(
ricea6e001fc2015-08-14 18:25:29273 NewURLRequestWithChildAndRoute(url, priority, child_id, route_id));
dcheng40ce7b382016-04-08 23:46:13274 std::unique_ptr<ResourceThrottle> throttle(scheduler_->ScheduleRequest(
ricea6e001fc2015-08-14 18:25:29275 child_id, route_id, is_async, url_request.get()));
Jeremy Roman04f27c372017-10-27 15:20:55276 auto request = std::make_unique<TestRequest>(
avi933295f52017-01-03 19:50:27277 std::move(url_request), std::move(throttle), scheduler());
[email protected]a9344092d2013-02-27 00:56:45278 request->Start();
279 return request;
280 }
281
[email protected]0cb0e55b2013-03-24 04:58:21282 void ChangeRequestPriority(TestRequest* request,
[email protected]ed038bf2014-04-07 22:02:39283 net::RequestPriority new_priority,
284 int intra_priority = 0) {
ricea6e001fc2015-08-14 18:25:29285 request->ChangePriority(new_priority, intra_priority);
[email protected]0cb0e55b2013-03-24 04:58:21286 }
287
[email protected]1a718bd2014-07-30 01:22:22288 void FireCoalescingTimer() {
289 EXPECT_TRUE(mock_timer_->IsRunning());
290 mock_timer_->Fire();
291 }
292
Devdeep Ray5374e932017-07-26 16:44:27293 void RequestLimitOverrideConfigTestHelper(bool experiment_status) {
294 base::test::ScopedFeatureList scoped_feature_list;
Tarun Bansale45b03432017-08-22 17:32:25295 InitializeThrottleDelayableExperiment(&scoped_feature_list,
296 experiment_status, 0.0);
Devdeep Ray5374e932017-07-26 16:44:27297
298 // Set BDP to 120 kbits, which lies in the first configuration bucket. Set
299 // the effective connection type to Slow-2G, which is slower than the
300 // threshold configured in |InitializeMaxDelayableRequestsExperiment|. Needs
301 // to be done before initializing the scheduler because the client is
302 // created on the call to |InitializeScheduler|, which is where the initial
303 // limits for the delayable requests in flight are computed.
304 network_quality_estimator_.set_bandwidth_delay_product_kbits(120);
305 network_quality_estimator_.set_effective_connection_type(
306 net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
307 // Initialize the scheduler.
308 InitializeScheduler();
309
310 // For 2G, the typical values of RTT and bandwidth should result in the
311 // override taking effect with the experiment enabled. For this case, the
312 // new limit is 2. The limit will matter only once the page has a body,
313 // since delayable requests are not loaded before that.
314 scheduler()->OnWillInsertBody(kChildId, kRouteId);
315
316 // Throw in one high priority request to ensure that it does not matter once
317 // a body exists.
318 std::unique_ptr<TestRequest> high2(
319 NewRequest("http://host/high2", net::HIGHEST));
320 EXPECT_TRUE(high2->started());
321
322 // Should match the configuration set by
323 // |InitializeMaxDelayableRequestsExperiment|
324 const int kOverriddenNumRequests = 2;
325
326 std::vector<std::unique_ptr<TestRequest>> lows_singlehost;
327 // Queue the maximum number of delayable requests that should be started
328 // before the resource scheduler starts throttling delayable requests.
329 for (int i = 0; i < kOverriddenNumRequests; ++i) {
330 std::string url = "http://host/low" + base::IntToString(i);
331 lows_singlehost.push_back(NewRequest(url.c_str(), net::LOWEST));
332 EXPECT_TRUE(lows_singlehost[i]->started());
333 }
334
335 std::unique_ptr<TestRequest> second_last_singlehost(
336 NewRequest("http://host/s_last", net::LOWEST));
337 std::unique_ptr<TestRequest> last_singlehost(
338 NewRequest("http://host/last", net::LOWEST));
339
340 if (experiment_status) {
341 // Experiment enabled, hence requests should be limited.
342 // Second last should not start because there are |kOverridenNumRequests|
343 // delayable requests already in-flight.
344 EXPECT_FALSE(second_last_singlehost->started());
345
346 // Completion of a delayable request must result in starting of the
347 // second-last request.
348 lows_singlehost.erase(lows_singlehost.begin());
349 base::RunLoop().RunUntilIdle();
350 EXPECT_TRUE(second_last_singlehost->started());
351 EXPECT_FALSE(last_singlehost->started());
352
353 // Completion of another delayable request must result in starting of the
354 // last request.
355 lows_singlehost.erase(lows_singlehost.begin());
356 base::RunLoop().RunUntilIdle();
357 EXPECT_TRUE(last_singlehost->started());
358 } else {
359 // Requests should start because the default limit is 10.
360 EXPECT_TRUE(second_last_singlehost->started());
361 EXPECT_TRUE(last_singlehost->started());
362 }
363 }
364
Tarun Bansale45b03432017-08-22 17:32:25365 void InitializeThrottleDelayableExperiment(
Devdeep Ray86d04e22017-08-08 05:50:57366 base::test::ScopedFeatureList* scoped_feature_list,
Tarun Bansale45b03432017-08-22 17:32:25367 bool lower_delayable_count_enabled,
Devdeep Ray86d04e22017-08-08 05:50:57368 double non_delayable_weight) {
369 std::map<std::string, std::string> params;
Tarun Bansale45b03432017-08-22 17:32:25370 bool experiment_enabled = false;
371 if (lower_delayable_count_enabled) {
372 experiment_enabled = true;
373 params["MaxEffectiveConnectionType"] = "2G";
374 params["MaxBDPKbits1"] = "130";
375 params["MaxDelayableRequests1"] = "2";
376 params["MaxBDPKbits2"] = "160";
377 params["MaxDelayableRequests2"] = "4";
378 }
379
380 if (non_delayable_weight > 0.0) {
381 experiment_enabled = true;
382 params["MaxEffectiveConnectionType"] = "2G";
Brett Wilson5ed06e72017-12-01 01:25:11383 params["NonDelayableWeight"] = base::NumberToString(non_delayable_weight);
Tarun Bansale45b03432017-08-22 17:32:25384 }
385
386 base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting();
387 const char kTrialName[] = "TrialName";
388 const char kGroupName[] = "GroupName";
389
390 ASSERT_TRUE(
391 base::AssociateFieldTrialParams(kTrialName, kGroupName, params));
392 base::FieldTrial* field_trial =
393 base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName);
394 ASSERT_TRUE(field_trial);
395
396 std::unique_ptr<base::FeatureList> feature_list(
Jeremy Roman04f27c372017-10-27 15:20:55397 std::make_unique<base::FeatureList>());
Tarun Bansale45b03432017-08-22 17:32:25398 feature_list->RegisterFieldTrialOverride(
399 "ThrottleDelayable",
400 experiment_enabled ? base::FeatureList::OVERRIDE_ENABLE_FEATURE
401 : base::FeatureList::OVERRIDE_DISABLE_FEATURE,
402 field_trial);
403 scoped_feature_list->InitWithFeatureList(std::move(feature_list));
Devdeep Ray86d04e22017-08-08 05:50:57404 }
405
Devdeep Ray3d467db2017-07-25 01:06:46406 void ReadConfigTestHelper(size_t num_bdp_ranges,
407 const std::string& max_ect_string) {
408 base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting();
409 const char kTrialName[] = "TrialName";
410 const char kGroupName[] = "GroupName";
Tarun Bansale45b03432017-08-22 17:32:25411 const char kThrottleDelayable[] = "ThrottleDelayable";
Devdeep Ray3d467db2017-07-25 01:06:46412
413 base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting();
414 base::test::ScopedFeatureList scoped_feature_list;
415 std::map<std::string, std::string> params;
416 params["MaxEffectiveConnectionType"] = max_ect_string;
417 for (size_t bdp_range_index = 1; bdp_range_index <= num_bdp_ranges;
418 bdp_range_index++) {
Brett Wilson5accd242017-11-30 22:07:32419 std::string index_str = base::NumberToString(bdp_range_index);
Devdeep Ray3d467db2017-07-25 01:06:46420 params["MaxBDPKbits" + index_str] = index_str + "00";
421 params["MaxDelayableRequests" + index_str] = index_str + "0";
422 }
423
424 base::AssociateFieldTrialParams(kTrialName, kGroupName, params);
425 base::FieldTrial* field_trial =
426 base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName);
427 std::unique_ptr<base::FeatureList> feature_list(
Jeremy Roman04f27c372017-10-27 15:20:55428 std::make_unique<base::FeatureList>());
Devdeep Ray3d467db2017-07-25 01:06:46429 feature_list->RegisterFieldTrialOverride(
Tarun Bansale45b03432017-08-22 17:32:25430 kThrottleDelayable, base::FeatureList::OVERRIDE_ENABLE_FEATURE,
431 field_trial);
Devdeep Ray3d467db2017-07-25 01:06:46432 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
433
434 ResourceScheduler::MaxRequestsForBDPRanges bdp_ranges =
435 ResourceScheduler::GetMaxDelayableRequestsExperimentConfigForTests();
436
437 // Check that the configuration was parsed and stored correctly.
438 ASSERT_EQ(bdp_ranges.size(), num_bdp_ranges);
439 for (size_t bdp_range_index = 1; bdp_range_index <= num_bdp_ranges;
440 bdp_range_index++) {
441 EXPECT_EQ(bdp_ranges[bdp_range_index - 1].max_bdp_kbits,
442 (int64_t)(bdp_range_index * 100));
443 EXPECT_EQ(bdp_ranges[bdp_range_index - 1].max_requests,
444 bdp_range_index * 10u);
445 }
Devdeep Ray3d467db2017-07-25 01:06:46446 }
447
Tarun Bansale45b03432017-08-22 17:32:25448 void NonDelayableThrottlesDelayableHelper(double non_delayable_weight) {
Devdeep Ray86d04e22017-08-08 05:50:57449 base::test::ScopedFeatureList scoped_feature_list;
450 // Should be in sync with .cc.
451 const int kDefaultMaxNumDelayableRequestsPerClient = 10;
452 // Initialize the experiment.
Tarun Bansale45b03432017-08-22 17:32:25453 InitializeThrottleDelayableExperiment(&scoped_feature_list, false,
454 non_delayable_weight);
Devdeep Ray86d04e22017-08-08 05:50:57455 network_quality_estimator_.set_effective_connection_type(
456 net::EFFECTIVE_CONNECTION_TYPE_2G);
457
458 InitializeScheduler();
459 // Limit will only trigger after the page has a body.
460 scheduler()->OnWillInsertBody(kChildId, kRouteId);
461 // Start one non-delayable request.
462 std::unique_ptr<TestRequest> non_delayable_request(
463 NewRequest("http://host/medium", net::MEDIUM));
464 // Start |kDefaultMaxNumDelayableRequestsPerClient - 1 *
465 // |non_delayable_weight| delayable requests. They should all start.
466 std::vector<std::unique_ptr<TestRequest>> delayable_requests;
467 for (int i = 0;
468 i < kDefaultMaxNumDelayableRequestsPerClient - non_delayable_weight;
469 ++i) {
470 delayable_requests.push_back(NewRequest(
471 base::StringPrintf("http://host%d/low", i).c_str(), net::LOWEST));
472 EXPECT_TRUE(delayable_requests.back()->started());
473 }
474 // The next delayable request should not start.
475 std::unique_ptr<TestRequest> last_low(
476 NewRequest("http://lasthost/low", net::LOWEST));
477 EXPECT_FALSE(last_low->started());
478 }
479
rdsmith34d4a6c2015-06-24 19:38:55480 ResourceScheduler* scheduler() {
481 return scheduler_.get();
482 }
483
gab606d46c2016-11-09 23:07:21484 TestBrowserThreadBundle thread_bundle_;
dcheng40ce7b382016-04-08 23:46:13485 std::unique_ptr<ResourceScheduler> scheduler_;
[email protected]1a718bd2014-07-30 01:22:22486 base::MockTimer* mock_timer_;
[email protected]3ccdeec12013-05-02 16:36:53487 net::HttpServerPropertiesImpl http_server_properties_;
Devdeep Ray3d467db2017-07-25 01:06:46488 net::TestNetworkQualityEstimator network_quality_estimator_;
[email protected]a9344092d2013-02-27 00:56:45489 net::TestURLRequestContext context_;
Devdeep Ray3d467db2017-07-25 01:06:46490 base::FieldTrialList field_trial_list_;
[email protected]a9344092d2013-02-27 00:56:45491};
492
493TEST_F(ResourceSchedulerTest, OneIsolatedLowRequest) {
dcheng40ce7b382016-04-08 23:46:13494 std::unique_ptr<TestRequest> request(
495 NewRequest("http://host/1", net::LOWEST));
[email protected]a9344092d2013-02-27 00:56:45496 EXPECT_TRUE(request->started());
497}
498
[email protected]1d5a0ba2013-06-26 06:15:08499TEST_F(ResourceSchedulerTest, OneLowLoadsUntilBodyInserted) {
dcheng40ce7b382016-04-08 23:46:13500 std::unique_ptr<TestRequest> high(
501 NewRequest("http://host/high", net::HIGHEST));
502 std::unique_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
503 std::unique_ptr<TestRequest> low2(NewRequest("http://host/low", net::LOWEST));
[email protected]a9344092d2013-02-27 00:56:45504 EXPECT_TRUE(high->started());
[email protected]a9344092d2013-02-27 00:56:45505 EXPECT_TRUE(low->started());
[email protected]1d5a0ba2013-06-26 06:15:08506 EXPECT_FALSE(low2->started());
mmenke54c533a2015-10-08 21:30:32507
[email protected]e45329e92014-08-21 12:49:14508 high.reset();
mmenke54c533a2015-10-08 21:30:32509 base::RunLoop().RunUntilIdle();
pmeenanfcd44162016-06-04 14:47:25510 EXPECT_FALSE(low2->started());
mmenke54c533a2015-10-08 21:30:32511
rdsmith34d4a6c2015-06-24 19:38:55512 scheduler()->OnWillInsertBody(kChildId, kRouteId);
mmenke54c533a2015-10-08 21:30:32513 base::RunLoop().RunUntilIdle();
[email protected]1d5a0ba2013-06-26 06:15:08514 EXPECT_TRUE(low2->started());
[email protected]a9344092d2013-02-27 00:56:45515}
516
[email protected]e45329e92014-08-21 12:49:14517TEST_F(ResourceSchedulerTest, OneLowLoadsUntilCriticalComplete) {
dcheng40ce7b382016-04-08 23:46:13518 std::unique_ptr<TestRequest> high(
519 NewRequest("http://host/high", net::HIGHEST));
520 std::unique_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
521 std::unique_ptr<TestRequest> low2(NewRequest("http://host/low", net::LOWEST));
[email protected]e45329e92014-08-21 12:49:14522 EXPECT_TRUE(high->started());
523 EXPECT_TRUE(low->started());
524 EXPECT_FALSE(low2->started());
mmenke54c533a2015-10-08 21:30:32525
rdsmith34d4a6c2015-06-24 19:38:55526 scheduler()->OnWillInsertBody(kChildId, kRouteId);
mmenke54c533a2015-10-08 21:30:32527 base::RunLoop().RunUntilIdle();
[email protected]e45329e92014-08-21 12:49:14528 EXPECT_FALSE(low2->started());
mmenke54c533a2015-10-08 21:30:32529
[email protected]e45329e92014-08-21 12:49:14530 high.reset();
mmenke54c533a2015-10-08 21:30:32531 base::RunLoop().RunUntilIdle();
[email protected]e45329e92014-08-21 12:49:14532 EXPECT_TRUE(low2->started());
533}
534
pmeenanfcd44162016-06-04 14:47:25535TEST_F(ResourceSchedulerTest, MediumDoesNotBlockCriticalComplete) {
536 // kLayoutBlockingPriorityThreshold determines what priority level above which
537 // requests are considered layout-blocking and must be completed before the
538 // critical loading period is complete. It is currently set to net::MEDIUM.
539 std::unique_ptr<TestRequest> medium(
540 NewRequest("http://host/low", net::MEDIUM));
dcheng40ce7b382016-04-08 23:46:13541 std::unique_ptr<TestRequest> lowest(
542 NewRequest("http://host/lowest", net::LOWEST));
543 std::unique_ptr<TestRequest> lowest2(
pmeenan8a7d3a22014-10-16 19:43:03544 NewRequest("http://host/lowest", net::LOWEST));
pmeenanfcd44162016-06-04 14:47:25545 EXPECT_TRUE(medium->started());
pmeenan8a7d3a22014-10-16 19:43:03546 EXPECT_TRUE(lowest->started());
547 EXPECT_FALSE(lowest2->started());
mmenke54c533a2015-10-08 21:30:32548
rdsmith34d4a6c2015-06-24 19:38:55549 scheduler()->OnWillInsertBody(kChildId, kRouteId);
mmenke54c533a2015-10-08 21:30:32550 base::RunLoop().RunUntilIdle();
pmeenan8a7d3a22014-10-16 19:43:03551 EXPECT_TRUE(lowest2->started());
552}
553
Josh Karlin5b2b3d32017-08-31 13:08:38554TEST_F(ResourceSchedulerTest, SchedulerYieldsOnSpdy) {
jkarlinbf88dc8e2017-02-22 21:40:03555 base::test::ScopedFeatureList scoped_feature_list;
556 scoped_feature_list.InitFromCommandLine(kNetworkSchedulerYielding, "");
557 InitializeScheduler();
558
Josh Karlin5b2b3d32017-08-31 13:08:38559 // The second low-priority request should yield.
560 scheduler_->SetMaxRequestsBeforeYieldingForTesting(1);
561
562 // Set a custom yield time.
563 scheduler_->SetYieldTimeForTesting(base::TimeDelta::FromMilliseconds(42));
564
565 // Use a testing task runner so that we can control time.
566 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
567 scheduler_->SetTaskRunnerForTesting(task_runner);
568
jkarlinbf88dc8e2017-02-22 21:40:03569 http_server_properties_.SetSupportsSpdy(
570 url::SchemeHostPort("https", "spdyhost", 443), true);
571
Josh Karlin5b2b3d32017-08-31 13:08:38572 std::unique_ptr<TestRequest> request(
573 NewRequest("https://spdyhost/low", net::LOWEST));
574 std::unique_ptr<TestRequest> request2(
575 NewRequest("https://spdyhost/low", net::LOWEST));
576 std::unique_ptr<TestRequest> request3(
577 NewRequest("https://spdyhost/low", net::LOWEST));
jkarlinbf88dc8e2017-02-22 21:40:03578
Josh Karlin5b2b3d32017-08-31 13:08:38579 // Just before the yield task runs, only the first request should have
580 // started.
581 task_runner->FastForwardBy(base::TimeDelta::FromMilliseconds(41));
582 EXPECT_TRUE(request->started());
583 EXPECT_FALSE(request2->started());
584 EXPECT_FALSE(request3->started());
jkarlinbf88dc8e2017-02-22 21:40:03585
Josh Karlin5b2b3d32017-08-31 13:08:38586 // Yield is done, run the next task.
587 task_runner->FastForwardBy(base::TimeDelta::FromMilliseconds(1));
588 EXPECT_TRUE(request2->started());
589 EXPECT_FALSE(request3->started());
jkarlinbf88dc8e2017-02-22 21:40:03590
Josh Karlin5b2b3d32017-08-31 13:08:38591 // Just before the yield task runs, only the first two requests should have
592 // started.
593 task_runner->FastForwardBy(base::TimeDelta::FromMilliseconds(41));
594 EXPECT_FALSE(request3->started());
595
596 // Yield is done, run the next task.
597 task_runner->FastForwardBy(base::TimeDelta::FromMilliseconds(1));
598 EXPECT_TRUE(request3->started());
jkarlinbf88dc8e2017-02-22 21:40:03599}
600
Josh Karlin5b2b3d32017-08-31 13:08:38601// Same as SchedulerYieldsOnSpdy but uses FieldTrial Parameters for
602// configuration.
603TEST_F(ResourceSchedulerTest, SchedulerYieldFieldTrialParams) {
jkarlinbf88dc8e2017-02-22 21:40:03604 base::test::ScopedFeatureList scoped_feature_list;
Josh Karlin5b2b3d32017-08-31 13:08:38605
606 ConfigureYieldFieldTrial(1 /* requests before yielding */,
607 42 /* yield time */, &scoped_feature_list);
jkarlinbf88dc8e2017-02-22 21:40:03608 InitializeScheduler();
609
Josh Karlin5b2b3d32017-08-31 13:08:38610 // Make sure the parameters were properly set.
611 EXPECT_EQ(42, scheduler_->yield_time().InMilliseconds());
612 EXPECT_EQ(1, scheduler_->max_requests_before_yielding());
613
614 // Use a testing task runner so that we can control time.
615 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
616 scheduler_->SetTaskRunnerForTesting(task_runner);
617
jkarlinbf88dc8e2017-02-22 21:40:03618 http_server_properties_.SetSupportsSpdy(
619 url::SchemeHostPort("https", "spdyhost", 443), true);
620
Josh Karlin5b2b3d32017-08-31 13:08:38621 std::unique_ptr<TestRequest> request(
622 NewRequest("https://spdyhost/low", net::LOWEST));
623 std::unique_ptr<TestRequest> request2(
624 NewRequest("https://spdyhost/low", net::LOWEST));
jkarlinbf88dc8e2017-02-22 21:40:03625
Josh Karlin5b2b3d32017-08-31 13:08:38626 // Just before the yield task runs, only the first request should have
627 // started.
628 task_runner->FastForwardBy(base::TimeDelta::FromMilliseconds(41));
629 EXPECT_TRUE(request->started());
630 EXPECT_FALSE(request2->started());
jkarlinbf88dc8e2017-02-22 21:40:03631
Josh Karlin5b2b3d32017-08-31 13:08:38632 // Yield is done, run the next task.
633 task_runner->FastForwardBy(base::TimeDelta::FromMilliseconds(1));
634 EXPECT_TRUE(request2->started());
jkarlinbf88dc8e2017-02-22 21:40:03635}
636
Josh Karlin5b2b3d32017-08-31 13:08:38637TEST_F(ResourceSchedulerTest, YieldingDisabled) {
jkarlinbf88dc8e2017-02-22 21:40:03638 base::test::ScopedFeatureList scoped_feature_list;
639 scoped_feature_list.InitFromCommandLine("", kNetworkSchedulerYielding);
640 InitializeScheduler();
641
Josh Karlin5b2b3d32017-08-31 13:08:38642 // We're setting a yield parameter, but no yielding will happen since it's
643 // disabled.
644 scheduler_->SetMaxRequestsBeforeYieldingForTesting(1);
645
646 http_server_properties_.SetSupportsSpdy(
647 url::SchemeHostPort("https", "spdyhost", 443), true);
648
649 std::unique_ptr<TestRequest> request(
650 NewRequest("https://spdyhost/low", net::LOWEST));
651 std::unique_ptr<TestRequest> request2(
652 NewRequest("https://spdyhost/low", net::LOWEST));
653 EXPECT_TRUE(request->started());
654 EXPECT_TRUE(request2->started());
655}
656
657TEST_F(ResourceSchedulerTest, SchedulerDoesNotYieldH1) {
658 base::test::ScopedFeatureList scoped_feature_list;
659 scoped_feature_list.InitFromCommandLine(kNetworkSchedulerYielding, "");
660 InitializeScheduler();
661
662 // Use a testing task runner so that we can control time.
663 auto task_runner = base::MakeRefCounted<base::TestMockTimeTaskRunner>();
664 scheduler_->SetTaskRunnerForTesting(task_runner);
665
666 // Yield after each request.
667 scheduler_->SetMaxRequestsBeforeYieldingForTesting(1);
668 scheduler_->SetYieldTimeForTesting(base::TimeDelta::FromMilliseconds(42));
669
670 std::unique_ptr<TestRequest> request(
671 NewRequest("https://host/low", net::LOWEST));
672 std::unique_ptr<TestRequest> request2(
673 NewRequest("https://host/low", net::LOWEST));
674
675 EXPECT_TRUE(request->started());
676 EXPECT_FALSE(request2->started());
677
678 // Finish the first task so that the second can start.
679 request = nullptr;
680
681 // Run tasks without advancing time, if there were yielding the next task
682 // wouldn't start.
683 task_runner->RunUntilIdle();
684
685 // The next task started, so there was no yielding.
686 EXPECT_TRUE(request2->started());
687}
688
689TEST_F(ResourceSchedulerTest, SchedulerDoesNotYieldAltSchemes) {
690 base::test::ScopedFeatureList scoped_feature_list;
691 scoped_feature_list.InitFromCommandLine(kNetworkSchedulerYielding, "");
692 InitializeScheduler();
693
694 // Yield after each request.
695 scheduler_->SetMaxRequestsBeforeYieldingForTesting(1);
696 scheduler_->SetYieldTimeForTesting(base::TimeDelta::FromMilliseconds(42));
697
698 std::unique_ptr<TestRequest> request(
699 NewRequest("yyy://host/low", net::LOWEST));
700 std::unique_ptr<TestRequest> request2(
701 NewRequest("zzz://host/low", net::LOWEST));
702
703 EXPECT_TRUE(request->started());
704 EXPECT_TRUE(request2->started());
705}
706
707TEST_F(ResourceSchedulerTest, SchedulerDoesNotYieldSyncRequests) {
708 base::test::ScopedFeatureList scoped_feature_list;
709 scoped_feature_list.InitFromCommandLine(kNetworkSchedulerYielding, "");
710 InitializeScheduler();
711
712 // The second low-priority request should yield.
713 scheduler_->SetMaxRequestsBeforeYieldingForTesting(1);
714
jkarlinbf88dc8e2017-02-22 21:40:03715 // Use spdy so that we don't throttle.
716 http_server_properties_.SetSupportsSpdy(
717 url::SchemeHostPort("https", "spdyhost", 443), true);
718
Josh Karlin5b2b3d32017-08-31 13:08:38719 std::unique_ptr<TestRequest> request(
720 NewRequest("https://spdyhost/low", net::LOWEST));
721 std::unique_ptr<TestRequest> request2(
722 NewRequest("https://spdyhost/low", net::LOWEST)); // yields
jkarlinbf88dc8e2017-02-22 21:40:03723
Josh Karlin5b2b3d32017-08-31 13:08:38724 // Add a synchronous request, it shouldn't yield.
725 std::unique_ptr<TestRequest> sync_request(
726 NewSyncRequest("http://spdyhost/low", net::LOWEST));
727
728 EXPECT_TRUE(request->started());
729 EXPECT_FALSE(request2->started());
730 EXPECT_TRUE(sync_request->started()); // The sync request started.
731
732 base::RunLoop().RunUntilIdle();
733 EXPECT_TRUE(request2->started());
jkarlinbf88dc8e2017-02-22 21:40:03734}
735
[email protected]1d5a0ba2013-06-26 06:15:08736TEST_F(ResourceSchedulerTest, OneLowLoadsUntilBodyInsertedExceptSpdy) {
jkarlina9d98bd32016-10-19 18:45:48737 base::test::ScopedFeatureList scoped_feature_list;
738 scoped_feature_list.InitFromCommandLine("",
739 kPrioritySupportedRequestsDelayable);
740 InitializeScheduler();
741
[email protected]3ccdeec12013-05-02 16:36:53742 http_server_properties_.SetSupportsSpdy(
zhongyi3d4a55e72016-04-22 20:36:46743 url::SchemeHostPort("https", "spdyhost", 443), true);
dcheng40ce7b382016-04-08 23:46:13744 std::unique_ptr<TestRequest> high(
745 NewRequest("http://host/high", net::HIGHEST));
dcheng40ce7b382016-04-08 23:46:13746 std::unique_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
747 std::unique_ptr<TestRequest> low2(NewRequest("http://host/low", net::LOWEST));
pmeenanfcd44162016-06-04 14:47:25748 std::unique_ptr<TestRequest> low_spdy(
749 NewRequest("https://spdyhost/low", net::LOWEST));
[email protected]3ccdeec12013-05-02 16:36:53750 EXPECT_TRUE(high->started());
[email protected]3ccdeec12013-05-02 16:36:53751 EXPECT_TRUE(low->started());
[email protected]1d5a0ba2013-06-26 06:15:08752 EXPECT_FALSE(low2->started());
pmeenanfcd44162016-06-04 14:47:25753 EXPECT_TRUE(low_spdy->started());
mmenke54c533a2015-10-08 21:30:32754
rdsmith34d4a6c2015-06-24 19:38:55755 scheduler()->OnWillInsertBody(kChildId, kRouteId);
[email protected]e45329e92014-08-21 12:49:14756 high.reset();
mmenke54c533a2015-10-08 21:30:32757 base::RunLoop().RunUntilIdle();
[email protected]1d5a0ba2013-06-26 06:15:08758 EXPECT_TRUE(low2->started());
[email protected]3ccdeec12013-05-02 16:36:53759}
760
jkarlina9d98bd32016-10-19 18:45:48761TEST_F(ResourceSchedulerTest,
762 OneLowLoadsUntilBodyInsertedEvenSpdyWhenDelayable) {
jkarlinf390a5e42016-10-20 16:58:18763 base::test::ScopedFeatureList scoped_feature_list;
764 scoped_feature_list.InitFromCommandLine(kPrioritySupportedRequestsDelayable,
765 "");
766
767 InitializeScheduler();
jkarlina9d98bd32016-10-19 18:45:48768 http_server_properties_.SetSupportsSpdy(
769 url::SchemeHostPort("https", "spdyhost", 443), true);
770 std::unique_ptr<TestRequest> high(
771 NewRequest("http://host/high", net::HIGHEST));
772 std::unique_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
773 std::unique_ptr<TestRequest> low2(NewRequest("http://host/low", net::LOWEST));
774 std::unique_ptr<TestRequest> low_spdy(
775 NewRequest("https://spdyhost/low", net::LOWEST));
776 EXPECT_TRUE(high->started());
777 EXPECT_TRUE(low->started());
778 EXPECT_FALSE(low2->started());
779 EXPECT_FALSE(low_spdy->started());
780
781 scheduler()->OnWillInsertBody(kChildId, kRouteId);
782 high.reset();
783 base::RunLoop().RunUntilIdle();
784 EXPECT_TRUE(low2->started());
Josh Karlin40b0fcdb2017-08-28 15:33:54785 EXPECT_TRUE(low_spdy->started());
786}
787
788TEST_F(ResourceSchedulerTest, MaxRequestsPerHostForSpdyWhenNotDelayable) {
789 base::test::ScopedFeatureList scoped_feature_list;
790 scoped_feature_list.InitFromCommandLine("",
791 kPrioritySupportedRequestsDelayable);
792
793 InitializeScheduler();
794 http_server_properties_.SetSupportsSpdy(
795 url::SchemeHostPort("https", "spdyhost", 443), true);
796
797 // Add more than max-per-host low-priority requests.
798 std::vector<std::unique_ptr<TestRequest>> requests;
799 for (size_t i = 0; i < kMaxNumDelayableRequestsPerHostPerClient + 1; ++i)
800 requests.push_back(NewRequest("https://spdyhost/low", net::LOWEST));
801
802 // No throttling.
803 for (const auto& request : requests)
804 EXPECT_TRUE(request->started());
805}
806
807TEST_F(ResourceSchedulerTest, MaxRequestsPerHostForSpdyWhenDelayable) {
808 base::test::ScopedFeatureList scoped_feature_list;
809 scoped_feature_list.InitFromCommandLine(
810 kPrioritySupportedRequestsDelayable,
811 kHeadPrioritySupportedRequestsDelayable);
812
813 InitializeScheduler();
814 http_server_properties_.SetSupportsSpdy(
815 url::SchemeHostPort("https", "spdyhost", 443), true);
816
817 // Body has been reached.
818 scheduler()->OnWillInsertBody(kChildId, kRouteId);
819
820 // Add more than max-per-host low-priority requests.
821 std::vector<std::unique_ptr<TestRequest>> requests;
822 for (size_t i = 0; i < kMaxNumDelayableRequestsPerHostPerClient + 1; ++i)
823 requests.push_back(NewRequest("https://spdyhost/low", net::LOWEST));
824
825 // Only kMaxNumDelayableRequestsPerHostPerClient in body.
826 for (size_t i = 0; i < requests.size(); ++i) {
827 if (i < kMaxNumDelayableRequestsPerHostPerClient)
828 EXPECT_TRUE(requests[i]->started());
829 else
830 EXPECT_FALSE(requests[i]->started());
831 }
832}
833
834TEST_F(ResourceSchedulerTest, MaxRequestsPerHostForSpdyWhenHeadDelayable) {
835 base::test::ScopedFeatureList scoped_feature_list;
836 scoped_feature_list.InitFromCommandLine(
837 kHeadPrioritySupportedRequestsDelayable,
838 kPrioritySupportedRequestsDelayable);
839
840 InitializeScheduler();
841 http_server_properties_.SetSupportsSpdy(
842 url::SchemeHostPort("https", "spdyhost", 443), true);
843
844 // Body has been reached.
845 scheduler()->OnWillInsertBody(kChildId, kRouteId);
846
847 // Add more than max-per-host low-priority requests.
848 std::vector<std::unique_ptr<TestRequest>> requests;
849 for (size_t i = 0; i < kMaxNumDelayableRequestsPerHostPerClient + 1; ++i)
850 requests.push_back(NewRequest("https://spdyhost/low", net::LOWEST));
851
852 // No throttling.
853 for (const auto& request : requests)
854 EXPECT_TRUE(request->started());
855}
856
857TEST_F(ResourceSchedulerTest, ThrottlesHeadWhenHeadDelayable) {
858 base::test::ScopedFeatureList scoped_feature_list;
859 scoped_feature_list.InitFromCommandLine(
860 kHeadPrioritySupportedRequestsDelayable,
861 kPrioritySupportedRequestsDelayable);
862
863 InitializeScheduler();
864 http_server_properties_.SetSupportsSpdy(
865 url::SchemeHostPort("https", "spdyhost", 443), true);
866
867 // Add more than max-per-host low-priority requests.
868 std::vector<std::unique_ptr<TestRequest>> requests;
869 for (size_t i = 0; i < kMaxNumDelayableRequestsPerHostPerClient + 1; ++i)
870 requests.push_back(NewRequest("https://spdyhost/low", net::LOWEST));
871
872 // While in head, only one low-priority request is allowed.
873 for (size_t i = 0u; i < requests.size(); ++i) {
874 if (i == 0u)
875 EXPECT_TRUE(requests[i]->started());
876 else
877 EXPECT_FALSE(requests[i]->started());
878 }
879
880 // Body has been reached.
881 scheduler()->OnWillInsertBody(kChildId, kRouteId);
882 base::RunLoop().RunUntilIdle();
883
884 // No throttling.
885 for (const auto& request : requests)
886 EXPECT_TRUE(request->started());
887}
888
889TEST_F(ResourceSchedulerTest, MaxRequestsPerHostForSpdyProxyWhenNotDelayable) {
890 base::test::ScopedFeatureList scoped_feature_list;
891 scoped_feature_list.InitFromCommandLine("",
892 kPrioritySupportedRequestsDelayable);
893
894 InitializeScheduler();
895
896 // Body has been reached.
897 scheduler()->OnWillInsertBody(kChildId, kRouteId);
898
899 // Add more than max-per-host low-priority requests.
900 std::vector<std::unique_ptr<TestRequest>> requests;
901 for (size_t i = 0; i < kMaxNumDelayableRequestsPerHostPerClient + 1; ++i)
902 requests.push_back(NewRequest("http://host/low", net::LOWEST));
903
904 // Now the scheduler realizes these requests are for a spdy proxy.
905 scheduler()->OnReceivedSpdyProxiedHttpResponse(kChildId, kRouteId);
906 base::RunLoop().RunUntilIdle();
907
908 // No throttling.
909 for (const auto& request : requests)
910 EXPECT_TRUE(request->started());
911}
912
913TEST_F(ResourceSchedulerTest, MaxRequestsPerHostForSpdyProxyWhenDelayable) {
914 base::test::ScopedFeatureList scoped_feature_list;
915 scoped_feature_list.InitFromCommandLine(
916 kPrioritySupportedRequestsDelayable,
917 kHeadPrioritySupportedRequestsDelayable);
918
919 InitializeScheduler();
920
921 // Body has been reached.
922 scheduler()->OnWillInsertBody(kChildId, kRouteId);
923
924 // Add more than max-per-host low-priority requests.
925 std::vector<std::unique_ptr<TestRequest>> requests;
926 for (size_t i = 0; i < kMaxNumDelayableRequestsPerHostPerClient + 1; ++i)
927 requests.push_back(NewRequest("http://host/low", net::LOWEST));
928
929 // Now the scheduler realizes these requests are for a spdy proxy.
930 scheduler()->OnReceivedSpdyProxiedHttpResponse(kChildId, kRouteId);
931 base::RunLoop().RunUntilIdle();
932
933 // Only kMaxNumDelayableRequestsPerHostPerClient in body.
934 for (size_t i = 0; i < requests.size(); ++i) {
935 if (i < kMaxNumDelayableRequestsPerHostPerClient)
936 EXPECT_TRUE(requests[i]->started());
937 else
938 EXPECT_FALSE(requests[i]->started());
939 }
940}
941
942TEST_F(ResourceSchedulerTest, MaxRequestsPerHostForSpdyProxyWhenHeadDelayable) {
943 base::test::ScopedFeatureList scoped_feature_list;
944 scoped_feature_list.InitFromCommandLine(
945 kHeadPrioritySupportedRequestsDelayable,
946 kPrioritySupportedRequestsDelayable);
947
948 InitializeScheduler();
949
950 // Body has been reached.
951 scheduler()->OnWillInsertBody(kChildId, kRouteId);
952
953 // Add more than max-per-host low-priority requests.
954 std::vector<std::unique_ptr<TestRequest>> requests;
955 for (size_t i = 0; i < kMaxNumDelayableRequestsPerHostPerClient + 1; ++i)
956 requests.push_back(NewRequest("http://host/low", net::LOWEST));
957
958 // Now the scheduler realizes these requests are for a spdy proxy.
959 scheduler()->OnReceivedSpdyProxiedHttpResponse(kChildId, kRouteId);
960 base::RunLoop().RunUntilIdle();
961
962 // No throttling.
963 for (const auto& request : requests)
964 EXPECT_TRUE(request->started());
965}
966
967TEST_F(ResourceSchedulerTest, ThrottlesHeadForSpdyProxyWhenHeadDelayable) {
968 base::test::ScopedFeatureList scoped_feature_list;
969 scoped_feature_list.InitFromCommandLine(
970 kHeadPrioritySupportedRequestsDelayable,
971 kPrioritySupportedRequestsDelayable);
972
973 InitializeScheduler();
974
975 // Add more than max-per-host low-priority requests.
976 std::vector<std::unique_ptr<TestRequest>> requests;
977 for (size_t i = 0; i < kMaxNumDelayableRequestsPerHostPerClient + 1; ++i)
978 requests.push_back(NewRequest("http://host/low", net::LOWEST));
979
980 // Now the scheduler realizes these requests are for a spdy proxy.
981 scheduler()->OnReceivedSpdyProxiedHttpResponse(kChildId, kRouteId);
982 base::RunLoop().RunUntilIdle();
983
984 // While in head, only one low-priority request is allowed.
985 for (size_t i = 0u; i < requests.size(); ++i) {
986 if (i == 0u)
987 EXPECT_TRUE(requests[i]->started());
988 else
989 EXPECT_FALSE(requests[i]->started());
990 }
991
992 // Body has been reached.
993 scheduler()->OnWillInsertBody(kChildId, kRouteId);
994 base::RunLoop().RunUntilIdle();
995
996 // No throttling.
997 for (const auto& request : requests)
998 EXPECT_TRUE(request->started());
jkarlina9d98bd32016-10-19 18:45:48999}
1000
pmeenanfcd44162016-06-04 14:47:251001TEST_F(ResourceSchedulerTest, SpdyLowBlocksOtherLowUntilBodyInserted) {
1002 http_server_properties_.SetSupportsSpdy(
1003 url::SchemeHostPort("https", "spdyhost", 443), true);
1004 std::unique_ptr<TestRequest> high(
1005 NewRequest("http://host/high", net::HIGHEST));
1006 std::unique_ptr<TestRequest> low_spdy(
1007 NewRequest("https://spdyhost/low", net::LOWEST));
1008 std::unique_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
1009 EXPECT_TRUE(high->started());
1010 EXPECT_TRUE(low_spdy->started());
1011 EXPECT_FALSE(low->started());
1012
1013 scheduler()->OnWillInsertBody(kChildId, kRouteId);
1014 high.reset();
1015 base::RunLoop().RunUntilIdle();
1016 EXPECT_TRUE(low->started());
1017}
1018
[email protected]a9344092d2013-02-27 00:56:451019TEST_F(ResourceSchedulerTest, NavigationResetsState) {
tbansal29fc633862017-06-06 22:50:231020 base::HistogramTester histogram_tester;
rdsmith34d4a6c2015-06-24 19:38:551021 scheduler()->OnWillInsertBody(kChildId, kRouteId);
1022 scheduler()->OnNavigate(kChildId, kRouteId);
tbansal29fc633862017-06-06 22:50:231023
1024 {
1025 std::unique_ptr<TestRequest> high(
1026 NewRequest("http://host/high", net::HIGHEST));
1027 std::unique_ptr<TestRequest> low(
1028 NewRequest("http://host/low", net::LOWEST));
1029 std::unique_ptr<TestRequest> low2(
1030 NewRequest("http://host/low", net::LOWEST));
1031 EXPECT_TRUE(high->started());
1032 EXPECT_TRUE(low->started());
1033 EXPECT_FALSE(low2->started());
1034 }
1035
1036 histogram_tester.ExpectTotalCount("ResourceScheduler.RequestsCount.All", 2);
1037 EXPECT_THAT(
1038 histogram_tester.GetAllSamples("ResourceScheduler.RequestsCount.All"),
1039 testing::ElementsAre(base::Bucket(1, 1), base::Bucket(2, 1)));
1040
1041 histogram_tester.ExpectTotalCount("ResourceScheduler.RequestsCount.Delayable",
1042 2);
1043 histogram_tester.ExpectTotalCount(
1044 "ResourceScheduler.RequestsCount.NonDelayable", 2);
1045 histogram_tester.ExpectTotalCount(
1046 "ResourceScheduler.RequestsCount.TotalLayoutBlocking", 2);
1047
1048 histogram_tester.ExpectUniqueSample(
1049 "ResourceScheduler.PeakDelayableRequestsInFlight.LayoutBlocking", 1, 1);
1050 histogram_tester.ExpectUniqueSample(
1051 "ResourceScheduler.PeakDelayableRequestsInFlight.NonDelayable", 1, 1);
[email protected]a9344092d2013-02-27 00:56:451052}
1053
1054TEST_F(ResourceSchedulerTest, BackgroundRequestStartsImmediately) {
1055 const int route_id = 0; // Indicates a background request.
dcheng40ce7b382016-04-08 23:46:131056 std::unique_ptr<TestRequest> request(
1057 NewRequestWithRoute("http://host/1", net::LOWEST, route_id));
[email protected]a9344092d2013-02-27 00:56:451058 EXPECT_TRUE(request->started());
1059}
1060
pmeenanfcd44162016-06-04 14:47:251061TEST_F(ResourceSchedulerTest, MoreThanOneHighRequestBlocksDelayableRequests) {
1062 // If there are more than kInFlightNonDelayableRequestCountThreshold (=1)
1063 // high-priority / non-delayable requests, block all low priority fetches and
1064 // allow them through one at a time once the number of high priority requests
1065 // drops.
dcheng40ce7b382016-04-08 23:46:131066 std::unique_ptr<TestRequest> high1(
1067 NewRequest("http://host/high1", net::HIGHEST));
1068 std::unique_ptr<TestRequest> high2(
1069 NewRequest("http://host/high2", net::HIGHEST));
1070 std::unique_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
1071 std::unique_ptr<TestRequest> low2(NewRequest("http://host/low", net::LOWEST));
[email protected]a9344092d2013-02-27 00:56:451072 EXPECT_TRUE(high1->started());
1073 EXPECT_TRUE(high2->started());
pmeenanfcd44162016-06-04 14:47:251074 EXPECT_FALSE(low->started());
[email protected]1d5a0ba2013-06-26 06:15:081075 EXPECT_FALSE(low2->started());
mmenke54c533a2015-10-08 21:30:321076
[email protected]1d5a0ba2013-06-26 06:15:081077 high1.reset();
mmenke54c533a2015-10-08 21:30:321078 base::RunLoop().RunUntilIdle();
pmeenanfcd44162016-06-04 14:47:251079 EXPECT_TRUE(low->started());
[email protected]1d5a0ba2013-06-26 06:15:081080 EXPECT_FALSE(low2->started());
[email protected]a9344092d2013-02-27 00:56:451081}
1082
[email protected]a9344092d2013-02-27 00:56:451083TEST_F(ResourceSchedulerTest, CancelOtherRequestsWhileResuming) {
dcheng40ce7b382016-04-08 23:46:131084 std::unique_ptr<TestRequest> high(
1085 NewRequest("http://host/high", net::HIGHEST));
1086 std::unique_ptr<TestRequest> low1(
1087 NewRequest("http://host/low1", net::LOWEST));
[email protected]a9344092d2013-02-27 00:56:451088
dcheng40ce7b382016-04-08 23:46:131089 std::unique_ptr<net::URLRequest> url_request(
[email protected]afbbccbf2013-03-02 02:00:081090 NewURLRequest("http://host/low2", net::LOWEST));
dcheng40ce7b382016-04-08 23:46:131091 std::unique_ptr<ResourceThrottle> throttle(scheduler()->ScheduleRequest(
ricea6e001fc2015-08-14 18:25:291092 kChildId, kRouteId, true, url_request.get()));
dcheng40ce7b382016-04-08 23:46:131093 std::unique_ptr<CancelingTestRequest> low2(new CancelingTestRequest(
dcheng36b6aec92015-12-26 06:16:361094 std::move(url_request), std::move(throttle), scheduler()));
[email protected]a9344092d2013-02-27 00:56:451095 low2->Start();
1096
dcheng40ce7b382016-04-08 23:46:131097 std::unique_ptr<TestRequest> low3(
1098 NewRequest("http://host/low3", net::LOWEST));
dcheng36b6aec92015-12-26 06:16:361099 low2->set_request_to_cancel(std::move(low3));
dcheng40ce7b382016-04-08 23:46:131100 std::unique_ptr<TestRequest> low4(
1101 NewRequest("http://host/low4", net::LOWEST));
[email protected]a9344092d2013-02-27 00:56:451102
1103 EXPECT_TRUE(high->started());
1104 EXPECT_FALSE(low2->started());
mmenke54c533a2015-10-08 21:30:321105
pmeenanfcd44162016-06-04 14:47:251106 scheduler()->OnWillInsertBody(kChildId, kRouteId);
[email protected]a9344092d2013-02-27 00:56:451107 high.reset();
mmenke54c533a2015-10-08 21:30:321108 base::RunLoop().RunUntilIdle();
[email protected]a9344092d2013-02-27 00:56:451109 EXPECT_TRUE(low1->started());
1110 EXPECT_TRUE(low2->started());
1111 EXPECT_TRUE(low4->started());
1112}
1113
[email protected]0cb0e55b2013-03-24 04:58:211114TEST_F(ResourceSchedulerTest, LimitedNumberOfDelayableRequestsInFlight) {
jkarlinbf88dc8e2017-02-22 21:40:031115 // The yielding feature will sometimes yield requests before they get a
1116 // chance to start, which conflicts this test. So disable the feature.
1117 base::test::ScopedFeatureList scoped_feature_list;
1118 scoped_feature_list.InitFromCommandLine("", kNetworkSchedulerYielding);
1119
[email protected]0cb0e55b2013-03-24 04:58:211120 // We only load low priority resources if there's a body.
rdsmith34d4a6c2015-06-24 19:38:551121 scheduler()->OnWillInsertBody(kChildId, kRouteId);
[email protected]0cb0e55b2013-03-24 04:58:211122
1123 // Throw in one high priority request to make sure that's not a factor.
dcheng40ce7b382016-04-08 23:46:131124 std::unique_ptr<TestRequest> high(
1125 NewRequest("http://host/high", net::HIGHEST));
[email protected]0cb0e55b2013-03-24 04:58:211126 EXPECT_TRUE(high->started());
1127
Devdeep Rayca9665c2017-08-02 19:27:541128 const int kDefaultMaxNumDelayableRequestsPerClient =
1129 10; // Should match the .cc.
[email protected]e650b462013-11-18 03:26:411130 const int kMaxNumDelayableRequestsPerHost = 6;
avi933295f52017-01-03 19:50:271131 std::vector<std::unique_ptr<TestRequest>> lows_singlehost;
[email protected]e650b462013-11-18 03:26:411132 // Queue up to the per-host limit (we subtract the current high-pri request).
1133 for (int i = 0; i < kMaxNumDelayableRequestsPerHost - 1; ++i) {
[email protected]0cb0e55b2013-03-24 04:58:211134 string url = "http://host/low" + base::IntToString(i);
[email protected]e650b462013-11-18 03:26:411135 lows_singlehost.push_back(NewRequest(url.c_str(), net::LOWEST));
1136 EXPECT_TRUE(lows_singlehost[i]->started());
[email protected]0cb0e55b2013-03-24 04:58:211137 }
1138
dcheng40ce7b382016-04-08 23:46:131139 std::unique_ptr<TestRequest> second_last_singlehost(
1140 NewRequest("http://host/last", net::LOWEST));
1141 std::unique_ptr<TestRequest> last_singlehost(
1142 NewRequest("http://host/s_last", net::LOWEST));
[email protected]e650b462013-11-18 03:26:411143
1144 EXPECT_FALSE(second_last_singlehost->started());
mmenke54c533a2015-10-08 21:30:321145
[email protected]0cb0e55b2013-03-24 04:58:211146 high.reset();
mmenke54c533a2015-10-08 21:30:321147 base::RunLoop().RunUntilIdle();
[email protected]e650b462013-11-18 03:26:411148 EXPECT_TRUE(second_last_singlehost->started());
1149 EXPECT_FALSE(last_singlehost->started());
mmenke54c533a2015-10-08 21:30:321150
[email protected]e650b462013-11-18 03:26:411151 lows_singlehost.erase(lows_singlehost.begin());
mmenke54c533a2015-10-08 21:30:321152 base::RunLoop().RunUntilIdle();
[email protected]e650b462013-11-18 03:26:411153 EXPECT_TRUE(last_singlehost->started());
1154
1155 // Queue more requests from different hosts until we reach the total limit.
Devdeep Rayca9665c2017-08-02 19:27:541156 int expected_slots_left = kDefaultMaxNumDelayableRequestsPerClient -
1157 kMaxNumDelayableRequestsPerHost;
[email protected]e650b462013-11-18 03:26:411158 EXPECT_GT(expected_slots_left, 0);
avi933295f52017-01-03 19:50:271159 std::vector<std::unique_ptr<TestRequest>> lows_different_host;
mmenke54c533a2015-10-08 21:30:321160 base::RunLoop().RunUntilIdle();
[email protected]e650b462013-11-18 03:26:411161 for (int i = 0; i < expected_slots_left; ++i) {
1162 string url = "http://host" + base::IntToString(i) + "/low";
pmeenan9ac669682015-08-17 14:57:031163 lows_different_host.push_back(NewRequest(url.c_str(), net::LOWEST));
1164 EXPECT_TRUE(lows_different_host[i]->started());
[email protected]e650b462013-11-18 03:26:411165 }
1166
dcheng40ce7b382016-04-08 23:46:131167 std::unique_ptr<TestRequest> last_different_host(
1168 NewRequest("http://host_new/last", net::LOWEST));
pmeenan9ac669682015-08-17 14:57:031169 EXPECT_FALSE(last_different_host->started());
[email protected]0cb0e55b2013-03-24 04:58:211170}
1171
1172TEST_F(ResourceSchedulerTest, RaisePriorityAndStart) {
[email protected]1d5a0ba2013-06-26 06:15:081173 // Dummies to enforce scheduling.
dcheng40ce7b382016-04-08 23:46:131174 std::unique_ptr<TestRequest> high(
1175 NewRequest("http://host/high", net::HIGHEST));
1176 std::unique_ptr<TestRequest> low(NewRequest("http://host/req", net::LOWEST));
[email protected]0cb0e55b2013-03-24 04:58:211177
dcheng40ce7b382016-04-08 23:46:131178 std::unique_ptr<TestRequest> request(
1179 NewRequest("http://host/req", net::LOWEST));
[email protected]0cb0e55b2013-03-24 04:58:211180 EXPECT_FALSE(request->started());
1181
1182 ChangeRequestPriority(request.get(), net::HIGHEST);
mmenke54c533a2015-10-08 21:30:321183 base::RunLoop().RunUntilIdle();
[email protected]0cb0e55b2013-03-24 04:58:211184 EXPECT_TRUE(request->started());
1185}
1186
1187TEST_F(ResourceSchedulerTest, RaisePriorityInQueue) {
[email protected]1d5a0ba2013-06-26 06:15:081188 // Dummies to enforce scheduling.
dcheng40ce7b382016-04-08 23:46:131189 std::unique_ptr<TestRequest> high(
1190 NewRequest("http://host/high", net::HIGHEST));
1191 std::unique_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
[email protected]0cb0e55b2013-03-24 04:58:211192
dcheng40ce7b382016-04-08 23:46:131193 std::unique_ptr<TestRequest> request(
1194 NewRequest("http://host/req", net::IDLE));
1195 std::unique_ptr<TestRequest> idle(NewRequest("http://host/idle", net::IDLE));
[email protected]0cb0e55b2013-03-24 04:58:211196 EXPECT_FALSE(request->started());
1197 EXPECT_FALSE(idle->started());
1198
1199 ChangeRequestPriority(request.get(), net::LOWEST);
mmenke54c533a2015-10-08 21:30:321200 base::RunLoop().RunUntilIdle();
[email protected]0cb0e55b2013-03-24 04:58:211201 EXPECT_FALSE(request->started());
1202 EXPECT_FALSE(idle->started());
1203
Devdeep Rayca9665c2017-08-02 19:27:541204 const int kDefaultMaxNumDelayableRequestsPerClient =
1205 10; // Should match the .cc.
avi933295f52017-01-03 19:50:271206 std::vector<std::unique_ptr<TestRequest>> lows;
Devdeep Rayca9665c2017-08-02 19:27:541207 for (int i = 0; i < kDefaultMaxNumDelayableRequestsPerClient - 1; ++i) {
[email protected]0cb0e55b2013-03-24 04:58:211208 string url = "http://host/low" + base::IntToString(i);
1209 lows.push_back(NewRequest(url.c_str(), net::LOWEST));
1210 }
1211
rdsmith34d4a6c2015-06-24 19:38:551212 scheduler()->OnWillInsertBody(kChildId, kRouteId);
[email protected]e45329e92014-08-21 12:49:141213 high.reset();
mmenke54c533a2015-10-08 21:30:321214 base::RunLoop().RunUntilIdle();
[email protected]e45329e92014-08-21 12:49:141215
[email protected]0cb0e55b2013-03-24 04:58:211216 EXPECT_TRUE(request->started());
1217 EXPECT_FALSE(idle->started());
1218}
1219
1220TEST_F(ResourceSchedulerTest, LowerPriority) {
[email protected]1d5a0ba2013-06-26 06:15:081221 // Dummies to enforce scheduling.
dcheng40ce7b382016-04-08 23:46:131222 std::unique_ptr<TestRequest> high(
1223 NewRequest("http://host/high", net::HIGHEST));
1224 std::unique_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
[email protected]0cb0e55b2013-03-24 04:58:211225
dcheng40ce7b382016-04-08 23:46:131226 std::unique_ptr<TestRequest> request(
1227 NewRequest("http://host/req", net::LOWEST));
1228 std::unique_ptr<TestRequest> idle(NewRequest("http://host/idle", net::IDLE));
[email protected]0cb0e55b2013-03-24 04:58:211229 EXPECT_FALSE(request->started());
1230 EXPECT_FALSE(idle->started());
1231
1232 ChangeRequestPriority(request.get(), net::IDLE);
mmenke54c533a2015-10-08 21:30:321233 base::RunLoop().RunUntilIdle();
[email protected]0cb0e55b2013-03-24 04:58:211234 EXPECT_FALSE(request->started());
1235 EXPECT_FALSE(idle->started());
1236
Devdeep Rayca9665c2017-08-02 19:27:541237 const int kDefaultMaxNumDelayableRequestsPerClient =
1238 10; // Should match the .cc.
[email protected]1d5a0ba2013-06-26 06:15:081239 // 2 fewer filler requests: 1 for the "low" dummy at the start, and 1 for the
1240 // one at the end, which will be tested.
Devdeep Rayca9665c2017-08-02 19:27:541241 const int kNumFillerRequests = kDefaultMaxNumDelayableRequestsPerClient - 2;
avi933295f52017-01-03 19:50:271242 std::vector<std::unique_ptr<TestRequest>> lows;
[email protected]1d5a0ba2013-06-26 06:15:081243 for (int i = 0; i < kNumFillerRequests; ++i) {
[email protected]e650b462013-11-18 03:26:411244 string url = "http://host" + base::IntToString(i) + "/low";
[email protected]0cb0e55b2013-03-24 04:58:211245 lows.push_back(NewRequest(url.c_str(), net::LOWEST));
1246 }
1247
rdsmith34d4a6c2015-06-24 19:38:551248 scheduler()->OnWillInsertBody(kChildId, kRouteId);
[email protected]e45329e92014-08-21 12:49:141249 high.reset();
mmenke54c533a2015-10-08 21:30:321250 base::RunLoop().RunUntilIdle();
[email protected]e45329e92014-08-21 12:49:141251
[email protected]0cb0e55b2013-03-24 04:58:211252 EXPECT_FALSE(request->started());
1253 EXPECT_TRUE(idle->started());
1254}
1255
1256TEST_F(ResourceSchedulerTest, ReprioritizedRequestGoesToBackOfQueue) {
[email protected]1d5a0ba2013-06-26 06:15:081257 // Dummies to enforce scheduling.
dcheng40ce7b382016-04-08 23:46:131258 std::unique_ptr<TestRequest> high(
1259 NewRequest("http://host/high", net::HIGHEST));
1260 std::unique_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
[email protected]0cb0e55b2013-03-24 04:58:211261
dcheng40ce7b382016-04-08 23:46:131262 std::unique_ptr<TestRequest> request(
1263 NewRequest("http://host/req", net::LOWEST));
1264 std::unique_ptr<TestRequest> idle(NewRequest("http://host/idle", net::IDLE));
[email protected]0cb0e55b2013-03-24 04:58:211265 EXPECT_FALSE(request->started());
1266 EXPECT_FALSE(idle->started());
1267
Devdeep Rayca9665c2017-08-02 19:27:541268 const int kDefaultMaxNumDelayableRequestsPerClient =
1269 10; // Should match the .cc.
avi933295f52017-01-03 19:50:271270 std::vector<std::unique_ptr<TestRequest>> lows;
Devdeep Rayca9665c2017-08-02 19:27:541271 for (int i = 0; i < kDefaultMaxNumDelayableRequestsPerClient; ++i) {
[email protected]0cb0e55b2013-03-24 04:58:211272 string url = "http://host/low" + base::IntToString(i);
1273 lows.push_back(NewRequest(url.c_str(), net::LOWEST));
1274 }
1275
1276 ChangeRequestPriority(request.get(), net::IDLE);
mmenke54c533a2015-10-08 21:30:321277 base::RunLoop().RunUntilIdle();
[email protected]0cb0e55b2013-03-24 04:58:211278 EXPECT_FALSE(request->started());
1279 EXPECT_FALSE(idle->started());
1280
1281 ChangeRequestPriority(request.get(), net::LOWEST);
mmenke54c533a2015-10-08 21:30:321282 base::RunLoop().RunUntilIdle();
[email protected]0cb0e55b2013-03-24 04:58:211283 EXPECT_FALSE(request->started());
1284 EXPECT_FALSE(idle->started());
1285
rdsmith34d4a6c2015-06-24 19:38:551286 scheduler()->OnWillInsertBody(kChildId, kRouteId);
mmenke54c533a2015-10-08 21:30:321287 base::RunLoop().RunUntilIdle();
[email protected]0cb0e55b2013-03-24 04:58:211288 EXPECT_FALSE(request->started());
1289 EXPECT_FALSE(idle->started());
1290}
1291
[email protected]ed038bf2014-04-07 22:02:391292TEST_F(ResourceSchedulerTest, HigherIntraPriorityGoesToFrontOfQueue) {
1293 // Dummies to enforce scheduling.
dcheng40ce7b382016-04-08 23:46:131294 std::unique_ptr<TestRequest> high(
1295 NewRequest("http://host/high", net::HIGHEST));
1296 std::unique_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
[email protected]ed038bf2014-04-07 22:02:391297
Devdeep Rayca9665c2017-08-02 19:27:541298 const int kDefaultMaxNumDelayableRequestsPerClient =
1299 10; // Should match the .cc.
avi933295f52017-01-03 19:50:271300 std::vector<std::unique_ptr<TestRequest>> lows;
Devdeep Rayca9665c2017-08-02 19:27:541301 for (int i = 0; i < kDefaultMaxNumDelayableRequestsPerClient; ++i) {
[email protected]ed038bf2014-04-07 22:02:391302 string url = "http://host/low" + base::IntToString(i);
1303 lows.push_back(NewRequest(url.c_str(), net::IDLE));
1304 }
1305
dcheng40ce7b382016-04-08 23:46:131306 std::unique_ptr<TestRequest> request(
1307 NewRequest("http://host/req", net::IDLE));
[email protected]ed038bf2014-04-07 22:02:391308 EXPECT_FALSE(request->started());
1309
1310 ChangeRequestPriority(request.get(), net::IDLE, 1);
mmenke54c533a2015-10-08 21:30:321311 base::RunLoop().RunUntilIdle();
[email protected]ed038bf2014-04-07 22:02:391312 EXPECT_FALSE(request->started());
1313
rdsmith34d4a6c2015-06-24 19:38:551314 scheduler()->OnWillInsertBody(kChildId, kRouteId);
[email protected]e45329e92014-08-21 12:49:141315 high.reset();
mmenke54c533a2015-10-08 21:30:321316 base::RunLoop().RunUntilIdle();
[email protected]ed038bf2014-04-07 22:02:391317 EXPECT_TRUE(request->started());
1318}
1319
[email protected]fd84c152013-10-24 20:53:111320TEST_F(ResourceSchedulerTest, NonHTTPSchedulesImmediately) {
1321 // Dummies to enforce scheduling.
dcheng40ce7b382016-04-08 23:46:131322 std::unique_ptr<TestRequest> high(
1323 NewRequest("http://host/high", net::HIGHEST));
1324 std::unique_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
[email protected]fd84c152013-10-24 20:53:111325
dcheng40ce7b382016-04-08 23:46:131326 std::unique_ptr<TestRequest> request(
[email protected]fd84c152013-10-24 20:53:111327 NewRequest("chrome-extension://req", net::LOWEST));
1328 EXPECT_TRUE(request->started());
1329}
1330
[email protected]b304306c2014-01-08 23:47:551331TEST_F(ResourceSchedulerTest, SpdyProxySchedulesImmediately) {
jkarlina9d98bd32016-10-19 18:45:481332 base::test::ScopedFeatureList scoped_feature_list;
1333 scoped_feature_list.InitFromCommandLine("",
1334 kPrioritySupportedRequestsDelayable);
1335 InitializeScheduler();
1336
dcheng40ce7b382016-04-08 23:46:131337 std::unique_ptr<TestRequest> high(
1338 NewRequest("http://host/high", net::HIGHEST));
1339 std::unique_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
[email protected]b304306c2014-01-08 23:47:551340
dcheng40ce7b382016-04-08 23:46:131341 std::unique_ptr<TestRequest> request(
1342 NewRequest("http://host/req", net::IDLE));
[email protected]b304306c2014-01-08 23:47:551343 EXPECT_FALSE(request->started());
1344
rdsmith34d4a6c2015-06-24 19:38:551345 scheduler()->OnReceivedSpdyProxiedHttpResponse(kChildId, kRouteId);
mmenke54c533a2015-10-08 21:30:321346 base::RunLoop().RunUntilIdle();
[email protected]b304306c2014-01-08 23:47:551347 EXPECT_TRUE(request->started());
1348
dcheng40ce7b382016-04-08 23:46:131349 std::unique_ptr<TestRequest> after(
1350 NewRequest("http://host/after", net::IDLE));
[email protected]b304306c2014-01-08 23:47:551351 EXPECT_TRUE(after->started());
1352}
1353
jkarlina9d98bd32016-10-19 18:45:481354TEST_F(ResourceSchedulerTest, SpdyProxyDelayable) {
jkarlinf390a5e42016-10-20 16:58:181355 base::test::ScopedFeatureList scoped_feature_list;
1356 scoped_feature_list.InitFromCommandLine(kPrioritySupportedRequestsDelayable,
1357 "");
1358 InitializeScheduler();
1359
jkarlina9d98bd32016-10-19 18:45:481360 std::unique_ptr<TestRequest> high(
1361 NewRequest("http://host/high", net::HIGHEST));
1362 std::unique_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
1363
1364 std::unique_ptr<TestRequest> request(
1365 NewRequest("http://host/req", net::IDLE));
1366 EXPECT_FALSE(request->started());
1367
1368 scheduler()->OnReceivedSpdyProxiedHttpResponse(kChildId, kRouteId);
1369 base::RunLoop().RunUntilIdle();
1370 EXPECT_FALSE(request->started());
1371
1372 std::unique_ptr<TestRequest> after(
1373 NewRequest("http://host/after", net::IDLE));
1374 EXPECT_FALSE(after->started());
1375}
1376
[email protected]e5697562014-04-25 08:55:491377TEST_F(ResourceSchedulerTest, NewSpdyHostInDelayableRequests) {
jkarlina9d98bd32016-10-19 18:45:481378 base::test::ScopedFeatureList scoped_feature_list;
1379 scoped_feature_list.InitFromCommandLine("",
1380 kPrioritySupportedRequestsDelayable);
1381 InitializeScheduler();
1382
rdsmith34d4a6c2015-06-24 19:38:551383 scheduler()->OnWillInsertBody(kChildId, kRouteId);
Devdeep Rayca9665c2017-08-02 19:27:541384 const int kDefaultMaxNumDelayableRequestsPerClient =
1385 10; // Should match the .cc.
[email protected]e5697562014-04-25 08:55:491386
dcheng40ce7b382016-04-08 23:46:131387 std::unique_ptr<TestRequest> low1_spdy(
[email protected]e5697562014-04-25 08:55:491388 NewRequest("http://spdyhost1:8080/low", net::LOWEST));
1389 // Cancel a request after we learn the server supports SPDY.
avi933295f52017-01-03 19:50:271390 std::vector<std::unique_ptr<TestRequest>> lows;
Devdeep Rayca9665c2017-08-02 19:27:541391 for (int i = 0; i < kDefaultMaxNumDelayableRequestsPerClient - 1; ++i) {
[email protected]e5697562014-04-25 08:55:491392 string url = "http://host" + base::IntToString(i) + "/low";
1393 lows.push_back(NewRequest(url.c_str(), net::LOWEST));
1394 }
dcheng40ce7b382016-04-08 23:46:131395 std::unique_ptr<TestRequest> low1(NewRequest("http://host/low", net::LOWEST));
[email protected]e5697562014-04-25 08:55:491396 EXPECT_FALSE(low1->started());
1397 http_server_properties_.SetSupportsSpdy(
zhongyi3d4a55e72016-04-22 20:36:461398 url::SchemeHostPort("http", "spdyhost1", 8080), true);
[email protected]e5697562014-04-25 08:55:491399 low1_spdy.reset();
mmenke54c533a2015-10-08 21:30:321400 base::RunLoop().RunUntilIdle();
[email protected]e5697562014-04-25 08:55:491401 EXPECT_TRUE(low1->started());
1402
1403 low1.reset();
mmenke54c533a2015-10-08 21:30:321404 base::RunLoop().RunUntilIdle();
dcheng40ce7b382016-04-08 23:46:131405 std::unique_ptr<TestRequest> low2_spdy(
[email protected]e5697562014-04-25 08:55:491406 NewRequest("http://spdyhost2:8080/low", net::IDLE));
1407 // Reprioritize a request after we learn the server supports SPDY.
1408 EXPECT_TRUE(low2_spdy->started());
1409 http_server_properties_.SetSupportsSpdy(
zhongyi3d4a55e72016-04-22 20:36:461410 url::SchemeHostPort("http", "spdyhost2", 8080), true);
[email protected]e5697562014-04-25 08:55:491411 ChangeRequestPriority(low2_spdy.get(), net::LOWEST);
mmenke54c533a2015-10-08 21:30:321412 base::RunLoop().RunUntilIdle();
dcheng40ce7b382016-04-08 23:46:131413 std::unique_ptr<TestRequest> low2(NewRequest("http://host/low", net::LOWEST));
[email protected]e5697562014-04-25 08:55:491414 EXPECT_TRUE(low2->started());
1415}
1416
jkarlina9d98bd32016-10-19 18:45:481417TEST_F(ResourceSchedulerTest, NewDelayableSpdyHostInDelayableRequests) {
jkarlinf390a5e42016-10-20 16:58:181418 base::test::ScopedFeatureList scoped_feature_list;
1419 scoped_feature_list.InitFromCommandLine(kPrioritySupportedRequestsDelayable,
1420 "");
1421 InitializeScheduler();
1422
jkarlina9d98bd32016-10-19 18:45:481423 scheduler()->OnWillInsertBody(kChildId, kRouteId);
Devdeep Rayca9665c2017-08-02 19:27:541424 const int kDefaultMaxNumDelayableRequestsPerClient =
1425 10; // Should match the .cc.
jkarlina9d98bd32016-10-19 18:45:481426
1427 std::unique_ptr<TestRequest> low1_spdy(
1428 NewRequest("http://spdyhost1:8080/low", net::LOWEST));
1429 // Cancel a request after we learn the server supports SPDY.
avi933295f52017-01-03 19:50:271430 std::vector<std::unique_ptr<TestRequest>> lows;
Devdeep Rayca9665c2017-08-02 19:27:541431 for (int i = 0; i < kDefaultMaxNumDelayableRequestsPerClient - 1; ++i) {
jkarlina9d98bd32016-10-19 18:45:481432 string url = "http://host" + base::IntToString(i) + "/low";
1433 lows.push_back(NewRequest(url.c_str(), net::LOWEST));
1434 }
1435 std::unique_ptr<TestRequest> low1(NewRequest("http://host/low", net::LOWEST));
1436 EXPECT_FALSE(low1->started());
1437 http_server_properties_.SetSupportsSpdy(
1438 url::SchemeHostPort("http", "spdyhost1", 8080), true);
1439 low1_spdy.reset();
1440 base::RunLoop().RunUntilIdle();
1441 EXPECT_TRUE(low1->started());
1442
1443 low1.reset();
1444 base::RunLoop().RunUntilIdle();
1445 std::unique_ptr<TestRequest> low2_spdy(
1446 NewRequest("http://spdyhost2:8080/low", net::IDLE));
1447 // Reprioritize a request after we learn the server supports SPDY.
1448 EXPECT_TRUE(low2_spdy->started());
1449 http_server_properties_.SetSupportsSpdy(
1450 url::SchemeHostPort("http", "spdyhost2", 8080), true);
1451 ChangeRequestPriority(low2_spdy.get(), net::LOWEST);
1452 base::RunLoop().RunUntilIdle();
1453 std::unique_ptr<TestRequest> low2(NewRequest("http://host/low", net::LOWEST));
1454 EXPECT_FALSE(low2->started());
1455}
1456
rdsmithf6498182016-09-23 16:28:121457// Async revalidations which are not started when the tab is closed must be
ricea1ce1e092015-07-09 16:28:341458// started at some point, or they will hang around forever and prevent other
1459// async revalidations to the same URL from being issued.
1460TEST_F(ResourceSchedulerTest, RequestStartedAfterClientDeleted) {
Devdeep Ray3d467db2017-07-25 01:06:461461 scheduler_->OnClientCreated(kChildId2, kRouteId2,
1462 &network_quality_estimator_);
dcheng40ce7b382016-04-08 23:46:131463 std::unique_ptr<TestRequest> high(NewRequestWithChildAndRoute(
ricea1ce1e092015-07-09 16:28:341464 "http://host/high", net::HIGHEST, kChildId2, kRouteId2));
dcheng40ce7b382016-04-08 23:46:131465 std::unique_ptr<TestRequest> lowest1(NewRequestWithChildAndRoute(
ricea1ce1e092015-07-09 16:28:341466 "http://host/lowest", net::LOWEST, kChildId2, kRouteId2));
dcheng40ce7b382016-04-08 23:46:131467 std::unique_ptr<TestRequest> lowest2(NewRequestWithChildAndRoute(
ricea1ce1e092015-07-09 16:28:341468 "http://host/lowest", net::LOWEST, kChildId2, kRouteId2));
1469 EXPECT_FALSE(lowest2->started());
mmenke54c533a2015-10-08 21:30:321470
ricea1ce1e092015-07-09 16:28:341471 scheduler_->OnClientDeleted(kChildId2, kRouteId2);
1472 high.reset();
1473 lowest1.reset();
mmenke54c533a2015-10-08 21:30:321474 base::RunLoop().RunUntilIdle();
ricea1ce1e092015-07-09 16:28:341475 EXPECT_TRUE(lowest2->started());
1476}
1477
1478// The ResourceScheduler::Client destructor calls
1479// LoadAnyStartablePendingRequests(), which may start some pending requests.
1480// This test is to verify that requests will be started at some point
1481// even if they were not started by the destructor.
1482TEST_F(ResourceSchedulerTest, RequestStartedAfterClientDeletedManyDelayable) {
Devdeep Ray3d467db2017-07-25 01:06:461483 scheduler_->OnClientCreated(kChildId2, kRouteId2,
1484 &network_quality_estimator_);
dcheng40ce7b382016-04-08 23:46:131485 std::unique_ptr<TestRequest> high(NewRequestWithChildAndRoute(
ricea1ce1e092015-07-09 16:28:341486 "http://host/high", net::HIGHEST, kChildId2, kRouteId2));
Devdeep Rayca9665c2017-08-02 19:27:541487 const int kDefaultMaxNumDelayableRequestsPerClient = 10;
avi933295f52017-01-03 19:50:271488 std::vector<std::unique_ptr<TestRequest>> delayable_requests;
Devdeep Rayca9665c2017-08-02 19:27:541489 for (int i = 0; i < kDefaultMaxNumDelayableRequestsPerClient + 1; ++i) {
ricea1ce1e092015-07-09 16:28:341490 delayable_requests.push_back(NewRequestWithChildAndRoute(
1491 "http://host/lowest", net::LOWEST, kChildId2, kRouteId2));
1492 }
dcheng40ce7b382016-04-08 23:46:131493 std::unique_ptr<TestRequest> lowest(NewRequestWithChildAndRoute(
ricea1ce1e092015-07-09 16:28:341494 "http://host/lowest", net::LOWEST, kChildId2, kRouteId2));
1495 EXPECT_FALSE(lowest->started());
mmenke54c533a2015-10-08 21:30:321496
ricea1ce1e092015-07-09 16:28:341497 scheduler_->OnClientDeleted(kChildId2, kRouteId2);
1498 high.reset();
1499 delayable_requests.clear();
mmenke54c533a2015-10-08 21:30:321500 base::RunLoop().RunUntilIdle();
ricea1ce1e092015-07-09 16:28:341501 EXPECT_TRUE(lowest->started());
1502}
1503
Devdeep Ray3d467db2017-07-25 01:06:461504// Tests that the maximum number of delayable requests is overridden when the
Devdeep Ray5374e932017-07-26 16:44:271505// experiment is enabled. The BDP buckets are correct and the effective
1506// connection type is also in the configuration bucket.
1507TEST_F(ResourceSchedulerTest, RequestLimitOverrideEnabled) {
1508 RequestLimitOverrideConfigTestHelper(true);
1509}
Devdeep Ray3d467db2017-07-25 01:06:461510
Devdeep Ray5374e932017-07-26 16:44:271511// Tests that the maximum number of delayable requests is not overridden when
1512// the experiment is disabled. The BDP buckets are correct and the effective
1513// connection type is also in the configuration bucket.
1514TEST_F(ResourceSchedulerTest, RequestLimitOverrideDisabled) {
1515 RequestLimitOverrideConfigTestHelper(false);
Devdeep Ray3d467db2017-07-25 01:06:461516}
1517
1518// Test that the limit is not overridden when the effective connection type is
1519// not equal to any of the values provided in the experiment configuration.
1520TEST_F(ResourceSchedulerTest, RequestLimitOverrideOutsideECTRange) {
Devdeep Ray5374e932017-07-26 16:44:271521 base::test::ScopedFeatureList scoped_feature_list;
Tarun Bansale45b03432017-08-22 17:32:251522 InitializeThrottleDelayableExperiment(&scoped_feature_list, true, 0.0);
Devdeep Ray5374e932017-07-26 16:44:271523 InitializeScheduler();
Devdeep Ray3d467db2017-07-25 01:06:461524 for (net::EffectiveConnectionType ect :
1525 {net::EFFECTIVE_CONNECTION_TYPE_UNKNOWN,
1526 net::EFFECTIVE_CONNECTION_TYPE_OFFLINE,
1527 net::EFFECTIVE_CONNECTION_TYPE_3G, net::EFFECTIVE_CONNECTION_TYPE_4G}) {
Devdeep Ray3d467db2017-07-25 01:06:461528 // Set BDP to 120 kbits, which lies in the configuration bucket. Set the
1529 // effective connection type to a value for which the experiment should not
1530 // be run.
1531 network_quality_estimator_.set_bandwidth_delay_product_kbits(120);
1532 network_quality_estimator_.set_effective_connection_type(ect);
Devdeep Ray3d467db2017-07-25 01:06:461533
1534 // The limit will matter only once the page has a body, since delayable
1535 // requests are not loaded before that.
1536 scheduler()->OnWillInsertBody(kChildId, kRouteId);
1537
1538 // Throw in one high priority request to ensure that it does not matter once
1539 // a body exists.
1540 std::unique_ptr<TestRequest> high(
1541 NewRequest("http://host/high", net::HIGHEST));
1542 EXPECT_TRUE(high->started());
1543
1544 // Should be in sync with resource_scheduler.cc.
Devdeep Rayca9665c2017-08-02 19:27:541545 const int kDefaultMaxNumDelayableRequestsPerClient = 10;
Devdeep Ray3d467db2017-07-25 01:06:461546
1547 std::vector<std::unique_ptr<TestRequest>> lows_singlehost;
1548 // Queue up to the maximum limit. Use different host names to prevent the
1549 // per host limit from kicking in.
Devdeep Rayca9665c2017-08-02 19:27:541550 for (int i = 0; i < kDefaultMaxNumDelayableRequestsPerClient; ++i) {
Devdeep Ray3d467db2017-07-25 01:06:461551 // Keep unique hostnames to prevent the per host limit from kicking in.
1552 std::string url = "http://host" + base::IntToString(i) + "/low";
1553 lows_singlehost.push_back(NewRequest(url.c_str(), net::LOWEST));
1554 EXPECT_TRUE(lows_singlehost[i]->started());
1555 }
1556
1557 std::unique_ptr<TestRequest> last_singlehost(
1558 NewRequest("http://host/last", net::LOWEST));
1559
1560 // Last should not start because the maximum requests that can be in-flight
1561 // have already started.
1562 EXPECT_FALSE(last_singlehost->started());
1563 }
1564}
1565
1566// Test that the limit is not overridden when the effective connection type is
1567// valid, but the bandwidth delay product (BDP) does not lie in one of the
1568// buckets provided in the configuration.
1569TEST_F(ResourceSchedulerTest, RequestLimitOverrideConfigOutsideBDPRange) {
1570 base::test::ScopedFeatureList scoped_feature_list;
Tarun Bansale45b03432017-08-22 17:32:251571 InitializeThrottleDelayableExperiment(&scoped_feature_list, true, 0.0);
Devdeep Ray3d467db2017-07-25 01:06:461572 // The BDP should lie outside the provided ranges. Here, the BDP is set to
1573 // 200, which lies outside the configuration BDP buckets.
1574 // The effective connection type is set to Slow-2G.
1575 network_quality_estimator_.set_bandwidth_delay_product_kbits(200);
1576 network_quality_estimator_.set_effective_connection_type(
1577 net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
1578 InitializeScheduler();
1579
1580 // The limit should be the default limit, which is 10 delayable requests
1581 // in-flight. The limit will matter only once the page has a body, since
1582 // delayable requests are not loaded before that.
1583 scheduler()->OnWillInsertBody(kChildId, kRouteId);
1584
1585 // Throw in one high priority request to ensure that it does not matter once
1586 // a body exists.
1587 std::unique_ptr<TestRequest> high(
1588 NewRequest("http://host/high", net::HIGHEST));
1589 EXPECT_TRUE(high->started());
1590
1591 // Should be in sync with resource_scheduler.cc.
Devdeep Rayca9665c2017-08-02 19:27:541592 const int kDefaultMaxNumDelayableRequestsPerClient = 10;
Devdeep Ray3d467db2017-07-25 01:06:461593
1594 std::vector<std::unique_ptr<TestRequest>> lows_singlehost;
1595 // Queue up to the maximum limit. Use different host names to prevent the
1596 // per host limit from kicking in.
Devdeep Rayca9665c2017-08-02 19:27:541597 for (int i = 0; i < kDefaultMaxNumDelayableRequestsPerClient; ++i) {
Devdeep Ray3d467db2017-07-25 01:06:461598 // Keep unique hostnames to prevent the per host limit from kicking in.
1599 std::string url = "http://host" + base::IntToString(i) + "/low";
1600 lows_singlehost.push_back(NewRequest(url.c_str(), net::LOWEST));
1601 EXPECT_TRUE(lows_singlehost[i]->started());
1602 }
1603
1604 std::unique_ptr<TestRequest> last_singlehost(
1605 NewRequest("http://host/last", net::LOWEST));
1606
1607 // Last should not start because the maximum requests that can be in-flight
1608 // have already started.
1609 EXPECT_FALSE(last_singlehost->started());
1610}
1611
1612// Test that a change in network conditions midway during loading does not
1613// change the behavior of the resource scheduler.
1614TEST_F(ResourceSchedulerTest, RequestLimitOverrideFixedForPageLoad) {
1615 base::test::ScopedFeatureList scoped_feature_list;
Tarun Bansale45b03432017-08-22 17:32:251616 InitializeThrottleDelayableExperiment(&scoped_feature_list, true, 0.0);
Devdeep Ray3d467db2017-07-25 01:06:461617 // BDP value is in range for which the limit is overridden to 2. The
1618 // effective connection type is set to Slow-2G.
1619 network_quality_estimator_.set_bandwidth_delay_product_kbits(120);
1620 network_quality_estimator_.set_effective_connection_type(
1621 net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
1622 InitializeScheduler();
1623
1624 // The limit will matter only once the page has a body, since delayable
1625 // requests are not loaded before that.
1626 scheduler()->OnWillInsertBody(kChildId, kRouteId);
1627
1628 // Throw in one high priority request to ensure that it does not matter once
1629 // a body exists.
1630 std::unique_ptr<TestRequest> high(
1631 NewRequest("http://host/high", net::HIGHEST));
1632 EXPECT_TRUE(high->started());
1633
1634 // Should be based on the value set by
1635 // |InitializeMaxDelayableRequestsExperiment| for the given range.
1636 const int kOverriddenNumRequests = 2;
1637
1638 std::vector<std::unique_ptr<TestRequest>> lows_singlehost;
1639 // Queue up to the overridden limit.
1640 for (int i = 0; i < kOverriddenNumRequests; ++i) {
1641 // Keep unique hostnames to prevent the per host limit from kicking in.
1642 std::string url = "http://host" + base::IntToString(i) + "/low";
1643 lows_singlehost.push_back(NewRequest(url.c_str(), net::LOWEST));
1644 EXPECT_TRUE(lows_singlehost[i]->started());
1645 }
1646
1647 std::unique_ptr<TestRequest> second_last_singlehost(
1648 NewRequest("http://host/slast", net::LOWEST));
1649
1650 // This new request should not start because the limit has been reached.
1651 EXPECT_FALSE(second_last_singlehost->started());
1652 lows_singlehost.erase(lows_singlehost.begin());
1653 base::RunLoop().RunUntilIdle();
1654 EXPECT_TRUE(second_last_singlehost->started());
1655
1656 // Change the BDP to go outside the experiment buckets and change the network
1657 // type to 2G. This should not affect the limit calculated at the beginning of
1658 // the page load.
1659 network_quality_estimator_.set_bandwidth_delay_product_kbits(50);
1660 network_quality_estimator_.set_effective_connection_type(
1661 net::EFFECTIVE_CONNECTION_TYPE_2G);
1662
1663 std::unique_ptr<TestRequest> last_singlehost(
1664 NewRequest("http://host/last", net::LOWEST));
1665
1666 // Last should not start because the limit should not have changed.
1667 EXPECT_FALSE(last_singlehost->started());
1668}
1669
1670// Test that when the network quality changes such that the new limit is lower,
1671// and an |OnNavigate| event occurs, the new delayable requests don't start
1672// until the number of requests in flight have gone below the new limit.
1673TEST_F(ResourceSchedulerTest, RequestLimitReducedAcrossPageLoads) {
1674 base::test::ScopedFeatureList scoped_feature_list;
Tarun Bansale45b03432017-08-22 17:32:251675 InitializeThrottleDelayableExperiment(&scoped_feature_list, true, 0.0);
Devdeep Ray3d467db2017-07-25 01:06:461676 // BDP value is in range for which the limit is overridden to 4. The
1677 // effective connection type is set to Slow-2G.
1678 network_quality_estimator_.set_bandwidth_delay_product_kbits(150);
1679 network_quality_estimator_.set_effective_connection_type(
1680 net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
1681 InitializeScheduler();
1682
1683 // The limit will matter only once the page has a body, since delayable
1684 // requests are not loaded before that.
1685 scheduler()->OnWillInsertBody(kChildId, kRouteId);
1686
1687 // Throw in one high priority request to ensure that it does not matter once
1688 // a body exists.
1689 std::unique_ptr<TestRequest> high(
1690 NewRequest("http://host/high", net::HIGHEST));
1691 EXPECT_TRUE(high->started());
1692
1693 // The number of delayable requests allowed for the first page load.
1694 const int kNumDelayableHigh = 4;
1695 // The number of delayable requests allowed for the second page load.
1696 const int kNumDelayableLow = 2;
1697
1698 std::vector<std::unique_ptr<TestRequest>> delayable_first_page;
1699 // Queue up to the overridden limit.
1700 for (int i = 0; i < kNumDelayableHigh; ++i) {
1701 // Keep unique hostnames to prevent the per host limit from kicking in.
1702 std::string url = "http://host" + base::IntToString(i) + "/low1";
1703 delayable_first_page.push_back(NewRequest(url.c_str(), net::LOWEST));
1704 EXPECT_TRUE(delayable_first_page[i]->started());
1705 }
1706 // Change the network quality so that the BDP value is in range for which the
1707 // limit is overridden to 2. The effective connection type is set to
1708 // Slow-2G.
1709 network_quality_estimator_.set_bandwidth_delay_product_kbits(120);
1710 network_quality_estimator_.set_effective_connection_type(
1711 net::EFFECTIVE_CONNECTION_TYPE_SLOW_2G);
1712 // Trigger a navigation event which will recompute limits. Also insert a body,
1713 // because the limit matters only after the body exists.
1714 scheduler()->OnNavigate(kChildId, kRouteId);
1715 scheduler()->OnWillInsertBody(kChildId, kRouteId);
1716
1717 // Ensure that high priority requests still start.
1718 std::unique_ptr<TestRequest> high2(
1719 NewRequest("http://host/high2", net::HIGHEST));
1720 EXPECT_TRUE(high->started());
1721
1722 // Generate requests from second page. None of them should start because the
Tarun Bansale45b03432017-08-22 17:32:251723 // new limit is |kNumDelayableLow| and there are already |kNumDelayableHigh|
1724 // requests in flight.
Devdeep Ray3d467db2017-07-25 01:06:461725 std::vector<std::unique_ptr<TestRequest>> delayable_second_page;
1726 for (int i = 0; i < kNumDelayableLow; ++i) {
1727 // Keep unique hostnames to prevent the per host limit from kicking in.
1728 std::string url = "http://host" + base::IntToString(i) + "/low2";
1729 delayable_second_page.push_back(NewRequest(url.c_str(), net::LOWEST));
1730 EXPECT_FALSE(delayable_second_page[i]->started());
1731 }
1732
1733 // Finish 2 requests from first page load.
Tarun Bansale45b03432017-08-22 17:32:251734 for (int i = 0; i < kNumDelayableHigh - kNumDelayableLow; ++i) {
Devdeep Ray3d467db2017-07-25 01:06:461735 delayable_first_page.pop_back();
1736 }
1737 base::RunLoop().RunUntilIdle();
1738
Tarun Bansale45b03432017-08-22 17:32:251739 // Nothing should start because there are already |kNumDelayableLow| requests
1740 // in flight.
Devdeep Ray3d467db2017-07-25 01:06:461741 for (int i = 0; i < kNumDelayableLow; ++i) {
1742 EXPECT_FALSE(delayable_second_page[i]->started());
1743 }
1744
1745 // Remove all requests from the first page.
1746 delayable_first_page.clear();
1747 base::RunLoop().RunUntilIdle();
1748
1749 // Check that the requests from page 2 have started, since now there are 2
1750 // empty slots.
1751 for (int i = 0; i < kNumDelayableLow; ++i) {
1752 EXPECT_TRUE(delayable_second_page[i]->started());
1753 }
1754}
1755
1756// Test that a configuration without any BDP range is read correctly. In this
1757// case, the resource scheduler will fall back to the default limit.
1758TEST_F(ResourceSchedulerTest, ReadValidConfigTest0) {
1759 ReadConfigTestHelper(0, "2G");
1760}
1761
1762// Test that a configuration with 1 BDP range is read correctly.
1763TEST_F(ResourceSchedulerTest, ReadValidConfigTest1) {
1764 ReadConfigTestHelper(1, "2G");
1765}
1766
1767// Test that a configuration with 2 BDP ranges is read correctly.
1768TEST_F(ResourceSchedulerTest, ReadValidConfigTest2) {
1769 ReadConfigTestHelper(2, "2G");
1770}
1771
1772// Test that a configuration with 5 BDP ranges is read correctly.
1773TEST_F(ResourceSchedulerTest, ReadValidConfigTest5) {
1774 ReadConfigTestHelper(5, "2G");
1775}
1776
1777// Test that a configuration with bad strings does not break the parser, and
1778// the parser stops reading the configuration after it encounters the first
1779// missing index.
1780TEST_F(ResourceSchedulerTest, ReadInvalidConfigTest) {
1781 base::FieldTrialParamAssociator::GetInstance()->ClearAllParamsForTesting();
1782 const char kTrialName[] = "TrialName";
1783 const char kGroupName[] = "GroupName";
Tarun Bansale45b03432017-08-22 17:32:251784 const char kThrottleDelayable[] = "ThrottleDelayable";
Devdeep Ray3d467db2017-07-25 01:06:461785
1786 base::test::ScopedFeatureList scoped_feature_list;
1787 std::map<std::string, std::string> params;
1788 params["MaxEffectiveConnectionType"] = "2G";
1789 // Skip configuration parameters for index 2 to test that the parser stops
1790 // when it cannot find the parameters for an index.
1791 for (int bdp_range_index : {1, 3, 4}) {
1792 std::string index_str = base::IntToString(bdp_range_index);
1793 params["MaxBDPKbits" + index_str] = index_str + "00";
1794 params["MaxDelayableRequests" + index_str] = index_str + "0";
1795 }
1796 // Add some bad configuration strigs to ensure that the parser does not break.
1797 params["BadConfigParam1"] = "100";
1798 params["BadConfigParam2"] = "100";
1799
1800 base::AssociateFieldTrialParams(kTrialName, kGroupName, params);
1801 base::FieldTrial* field_trial =
1802 base::FieldTrialList::CreateFieldTrial(kTrialName, kGroupName);
1803 std::unique_ptr<base::FeatureList> feature_list(
Jeremy Roman04f27c372017-10-27 15:20:551804 std::make_unique<base::FeatureList>());
Devdeep Ray3d467db2017-07-25 01:06:461805 feature_list->RegisterFieldTrialOverride(
Tarun Bansale45b03432017-08-22 17:32:251806 kThrottleDelayable, base::FeatureList::OVERRIDE_ENABLE_FEATURE,
1807 field_trial);
Devdeep Ray3d467db2017-07-25 01:06:461808 scoped_feature_list.InitWithFeatureList(std::move(feature_list));
1809
1810 ResourceScheduler::MaxRequestsForBDPRanges bdp_ranges =
1811 ResourceScheduler::GetMaxDelayableRequestsExperimentConfigForTests();
1812
1813 // Only the first configuration parameter must be read because a match was not
1814 // found for index 2. The configuration parameters with index 3 and 4 must be
1815 // ignored, even though they are valid configuration parameters.
1816 EXPECT_EQ(bdp_ranges.size(), 1u);
1817 EXPECT_EQ(bdp_ranges[0].max_bdp_kbits, 100);
1818 EXPECT_EQ(bdp_ranges[0].max_requests, 10u);
1819}
1820
1821// Test that the maximum effective connection type is read correctly when it is
1822// set to "Slow-2G".
1823TEST_F(ResourceSchedulerTest, ReadMaxECTForExperimentTestSlow2G) {
1824 ReadConfigTestHelper(3, "Slow-2G");
1825}
1826
1827// Test that the maximum effective connection type is read correctly when it is
1828// set to "4G".
1829TEST_F(ResourceSchedulerTest, ReadMaxECTForExperimentTest4G) {
1830 ReadConfigTestHelper(3, "4G");
1831}
1832
Devdeep Ray86d04e22017-08-08 05:50:571833// Test that the default limit is used for delayable requests when the
1834// experiment is enabled, but the current effective connection type is higher
1835// than the maximum effective connection type set in the experiment
1836// configuration.
1837TEST_F(ResourceSchedulerTest, NonDelayableThrottlesDelayableOutsideECT) {
1838 base::test::ScopedFeatureList scoped_feature_list;
1839 const double kNonDelayableWeight = 2.0;
1840 const int kDefaultMaxNumDelayableRequestsPerClient =
1841 10; // Should be in sync with cc.
1842 // Initialize the experiment with |kNonDelayableWeight| as the weight of
1843 // non-delayable requests.
Tarun Bansale45b03432017-08-22 17:32:251844 InitializeThrottleDelayableExperiment(&scoped_feature_list, false,
1845 kNonDelayableWeight);
Devdeep Ray86d04e22017-08-08 05:50:571846 // Experiment should not run when the effective connection type is faster
1847 // than 2G.
1848 network_quality_estimator_.set_effective_connection_type(
1849 net::EFFECTIVE_CONNECTION_TYPE_3G);
1850 // Limit will only trigger after the page has a body.
1851
1852 InitializeScheduler();
1853 scheduler()->OnWillInsertBody(kChildId, kRouteId);
1854 // Insert one non-delayable request. This should not affect the number of
1855 // delayable requests started.
1856 std::unique_ptr<TestRequest> medium(
1857 NewRequest("http://host/medium", net::MEDIUM));
1858 ASSERT_TRUE(medium->started());
1859 // Start |kDefaultMaxNumDelayableRequestsPerClient| delayable requests and
1860 // verify that they all started.
1861 std::vector<std::unique_ptr<TestRequest>> delayable_requests;
1862 for (int i = 0; i < kDefaultMaxNumDelayableRequestsPerClient; ++i) {
1863 delayable_requests.push_back(NewRequest(
1864 base::StringPrintf("http://host%d/low", i).c_str(), net::LOWEST));
1865 EXPECT_TRUE(delayable_requests.back()->started());
1866 }
1867}
1868
1869// Test that delayable requests are throttled by the right amount as the number
1870// of non-delayable requests in-flight change.
1871TEST_F(ResourceSchedulerTest, NonDelayableThrottlesDelayableVaryNonDelayable) {
1872 base::test::ScopedFeatureList scoped_feature_list;
1873 const double kNonDelayableWeight = 2.0;
1874 const int kDefaultMaxNumDelayableRequestsPerClient =
1875 10; // Should be in sync with cc.
1876 // Initialize the experiment with |kNonDelayableWeight| as the weight of
1877 // non-delayable requests.
Tarun Bansale45b03432017-08-22 17:32:251878 InitializeThrottleDelayableExperiment(&scoped_feature_list, false,
1879 kNonDelayableWeight);
Devdeep Ray86d04e22017-08-08 05:50:571880 network_quality_estimator_.set_effective_connection_type(
1881 net::EFFECTIVE_CONNECTION_TYPE_2G);
1882
1883 InitializeScheduler();
1884 // Limit will only trigger after the page has a body.
1885 scheduler()->OnWillInsertBody(kChildId, kRouteId);
1886 for (int num_non_delayable = 0; num_non_delayable < 10; ++num_non_delayable) {
1887 base::RunLoop().RunUntilIdle();
1888 // Start the non-delayable requests.
1889 std::vector<std::unique_ptr<TestRequest>> non_delayable_requests;
1890 for (int i = 0; i < num_non_delayable; ++i) {
1891 non_delayable_requests.push_back(NewRequest(
1892 base::StringPrintf("http://host%d/medium", i).c_str(), net::MEDIUM));
1893 ASSERT_TRUE(non_delayable_requests.back()->started());
1894 }
1895 // Start |kDefaultMaxNumDelayableRequestsPerClient| - |num_non_delayable| *
1896 // |kNonDelayableWeight| delayable requests. They should all start.
1897 std::vector<std::unique_ptr<TestRequest>> delayable_requests;
1898 for (int i = 0; i < kDefaultMaxNumDelayableRequestsPerClient -
1899 num_non_delayable * kNonDelayableWeight;
1900 ++i) {
1901 delayable_requests.push_back(NewRequest(
1902 base::StringPrintf("http://host%d/low", i).c_str(), net::LOWEST));
1903 EXPECT_TRUE(delayable_requests.back()->started());
1904 }
1905 // The next delayable request should not start.
1906 std::unique_ptr<TestRequest> last_low(
1907 NewRequest("http://lasthost/low", net::LOWEST));
1908 EXPECT_FALSE(last_low->started());
1909 }
1910}
1911
1912// Test that the default limit is used for delayable requests in the presence of
1913// non-delayable requests when the non-delayable request weight is zero.
1914TEST_F(ResourceSchedulerTest, NonDelayableThrottlesDelayableWeight0) {
Tarun Bansale45b03432017-08-22 17:32:251915 NonDelayableThrottlesDelayableHelper(0.0);
Devdeep Ray86d04e22017-08-08 05:50:571916}
1917
1918// Test that each non-delayable request in-flight results in the reduction of
1919// one in the limit of delayable requests in-flight when the non-delayable
1920// request weight is 1.
1921TEST_F(ResourceSchedulerTest, NonDelayableThrottlesDelayableWeight1) {
Tarun Bansale45b03432017-08-22 17:32:251922 NonDelayableThrottlesDelayableHelper(1.0);
Devdeep Ray86d04e22017-08-08 05:50:571923}
1924
1925// Test that each non-delayable request in-flight results in the reduction of
1926// three in the limit of delayable requests in-flight when the non-delayable
1927// request weight is 3.
1928TEST_F(ResourceSchedulerTest, NonDelayableThrottlesDelayableWeight3) {
Tarun Bansale45b03432017-08-22 17:32:251929 NonDelayableThrottlesDelayableHelper(3.0);
Devdeep Ray86d04e22017-08-08 05:50:571930}
1931
1932// Test that UMA counts are recorded for the number of delayable requests
1933// in-flight when a non-delayable request starts.
1934TEST_F(ResourceSchedulerTest, NumDelayableAtStartOfNonDelayableUMA) {
1935 std::unique_ptr<base::HistogramTester> histogram_tester(
1936 new base::HistogramTester);
1937 scheduler()->OnWillInsertBody(kChildId, kRouteId);
1938 // Check that 0 is recorded when a non-delayable request starts and there are
1939 // no delayable requests in-flight.
1940 std::unique_ptr<TestRequest> high(
1941 NewRequest("http://host/high", net::HIGHEST));
1942 EXPECT_TRUE(high->started());
1943 histogram_tester->ExpectUniqueSample(
1944 "ResourceScheduler.NumDelayableRequestsInFlightAtStart.NonDelayable", 0,
1945 1);
1946 histogram_tester.reset(new base::HistogramTester);
1947 // Check that nothing is recorded when delayable request is started in the
1948 // presence of a non-delayable request.
1949 std::unique_ptr<TestRequest> low1(
1950 NewRequest("http://host/low1", net::LOWEST));
1951 EXPECT_TRUE(low1->started());
1952 histogram_tester->ExpectTotalCount(
1953 "ResourceScheduler.NumDelayableRequestsInFlightAtStart.NonDelayable", 0);
1954 // Check that nothing is recorded when a delayable request is started in the
1955 // presence of another delayable request.
1956 std::unique_ptr<TestRequest> low2(
1957 NewRequest("http://host/low2", net::LOWEST));
1958 histogram_tester->ExpectTotalCount(
1959 "ResourceScheduler.NumDelayableRequestsInFlightAtStart.NonDelayable", 0);
1960 // Check that UMA is recorded when a non-delayable startes in the presence of
1961 // delayable requests and that the correct value is recorded.
1962 std::unique_ptr<TestRequest> high2(
1963 NewRequest("http://host/high2", net::HIGHEST));
1964 histogram_tester->ExpectUniqueSample(
1965 "ResourceScheduler.NumDelayableRequestsInFlightAtStart.NonDelayable", 2,
1966 1);
1967}
1968
Alex Clarke9155a342017-09-15 10:56:591969TEST_F(ResourceSchedulerTest, SchedulerEnabled) {
1970 std::unique_ptr<TestRequest> high(
1971 NewRequest("http://host/high", net::HIGHEST));
1972 std::unique_ptr<TestRequest> low(NewRequest("http://host/req", net::LOWEST));
1973
1974 std::unique_ptr<TestRequest> request(
1975 NewRequest("http://host/req", net::LOWEST));
1976
1977 EXPECT_FALSE(request->started());
1978}
1979
1980TEST_F(ResourceSchedulerTest, SchedulerDisabled) {
1981 InitializeScheduler(false);
1982
1983 std::unique_ptr<TestRequest> high(
1984 NewRequest("http://host/high", net::HIGHEST));
1985 std::unique_ptr<TestRequest> low(NewRequest("http://host/req", net::LOWEST));
1986
1987 std::unique_ptr<TestRequest> request(
1988 NewRequest("http://host/req", net::LOWEST));
1989
1990 // Normally |request| wouldn't start immediately due to the |high| priority
1991 // request, but when the scheduler is disabled it starts immediately.
1992 EXPECT_TRUE(request->started());
1993}
1994
[email protected]a9344092d2013-02-27 00:56:451995} // unnamed namespace
1996
1997} // namespace content