Chromium Code Reviews
chromiumcodereview-hr@appspot.gserviceaccount.com (chromiumcodereview-hr) | Please choose your nickname with Settings | Help | Chromium Project | Gerrit Changes | Sign out
(183)

Side by Side Diff: content/browser/loader/resource_scheduler_unittest.cc

Issue 12874003: Limit to only 10 image requests per page in ResourceScheduler. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src
Patch Set: Rebase Created 7 years, 9 months ago
Use n/p to move between diff chunks; N/P to move between comments. Draft comments are only viewable by you.
Jump to:
View unified diff | Download patch | Annotate | Revision Log
« no previous file with comments | « content/browser/loader/resource_scheduler.cc ('k') | no next file » | no next file with comments »
Toggle Intra-line Diffs ('i') | Expand Comments ('e') | Collapse Comments ('c') | Show Comments Hide Comments ('s')
OLDNEW
1 // Copyright (c) 2012 The Chromium Authors. All rights reserved. 1 // 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 2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file. 3 // found in the LICENSE file.
4 4
5 #include "content/browser/loader/resource_scheduler.h" 5 #include "content/browser/loader/resource_scheduler.h"
6 6
7 #include "base/memory/scoped_vector.h"
7 #include "base/message_loop.h" 8 #include "base/message_loop.h"
9 #include "base/strings/string_number_conversions.h"
8 #include "content/browser/browser_thread_impl.h" 10 #include "content/browser/browser_thread_impl.h"
9 #include "content/browser/loader/resource_dispatcher_host_impl.h" 11 #include "content/browser/loader/resource_dispatcher_host_impl.h"
12 #include "content/browser/loader/resource_message_filter.h"
10 #include "content/browser/loader/resource_request_info_impl.h" 13 #include "content/browser/loader/resource_request_info_impl.h"
14 #include "content/common/resource_messages.h"
15 #include "content/public/browser/resource_context.h"
11 #include "content/public/browser/resource_controller.h" 16 #include "content/public/browser/resource_controller.h"
12 #include "content/public/browser/resource_throttle.h" 17 #include "content/public/browser/resource_throttle.h"
18 #include "content/public/common/process_type.h"
13 #include "net/url_request/url_request.h" 19 #include "net/url_request/url_request.h"
14 #include "net/url_request/url_request_test_util.h" 20 #include "net/url_request/url_request_test_util.h"
15 #include "testing/gtest/include/gtest/gtest.h" 21 #include "testing/gtest/include/gtest/gtest.h"
16 #include "webkit/glue/resource_type.h" 22 #include "webkit/glue/resource_type.h"
17 23
18 namespace content { 24 namespace content {
19 25
20 namespace { 26 namespace {
21 27
22 class TestRequestFactory; 28 class TestRequestFactory;
(...skipping 12 matching lines...) Expand all
35 } 41 }
36 42
37 bool started() const { return started_; } 43 bool started() const { return started_; }
38 44
39 void Start() { 45 void Start() {
40 bool deferred = false; 46 bool deferred = false;
41 throttle_->WillStartRequest(&deferred); 47 throttle_->WillStartRequest(&deferred);
42 started_ = !deferred; 48 started_ = !deferred;
43 } 49 }
44 50
51 const net::URLRequest* url_request() const { return url_request_.get(); }
52
45 protected: 53 protected:
46 // ResourceController interface: 54 // ResourceController interface:
47 virtual void Cancel() OVERRIDE {} 55 virtual void Cancel() OVERRIDE {}
48 virtual void CancelAndIgnore() OVERRIDE {} 56 virtual void CancelAndIgnore() OVERRIDE {}
49 virtual void CancelWithError(int error_code) OVERRIDE {} 57 virtual void CancelWithError(int error_code) OVERRIDE {}
50 virtual void Resume() OVERRIDE { started_ = true; } 58 virtual void Resume() OVERRIDE { started_ = true; }
51 59
52 private: 60 private:
53 bool started_; 61 bool started_;
54 scoped_ptr<ResourceThrottle> throttle_; 62 scoped_ptr<ResourceThrottle> throttle_;
(...skipping 13 matching lines...) Expand all
68 76
69 private: 77 private:
70 virtual void Resume() OVERRIDE { 78 virtual void Resume() OVERRIDE {
71 TestRequest::Resume(); 79 TestRequest::Resume();
72 request_to_cancel_.reset(); 80 request_to_cancel_.reset();
73 } 81 }
74 82
75 scoped_ptr<TestRequest> request_to_cancel_; 83 scoped_ptr<TestRequest> request_to_cancel_;
76 }; 84 };
77 85
86 class FakeResourceContext : public ResourceContext {
87 private:
88 virtual net::HostResolver* GetHostResolver() OVERRIDE { return NULL; }
89 virtual net::URLRequestContext* GetRequestContext() OVERRIDE { return NULL; }
90 };
91
92 class FakeURLRequestContextSelector
93 : public ResourceMessageFilter::URLRequestContextSelector {
94 private:
95 virtual net::URLRequestContext* GetRequestContext(
96 ResourceType::Type) OVERRIDE {
97 return NULL;
98 }
99 };
100
101 class FakeResourceMessageFilter : public ResourceMessageFilter {
102 public:
103 FakeResourceMessageFilter(int child_id)
104 : ResourceMessageFilter(child_id,
105 PROCESS_TYPE_RENDERER,
106 &context_,
107 NULL /* appcache_service */,
108 NULL /* blob_storage_context */,
109 NULL /* file_system_context */,
110 new FakeURLRequestContextSelector) {
111 }
112
113 private:
114 virtual ~FakeResourceMessageFilter() {}
115
116 FakeResourceContext context_;
117 };
118
78 class ResourceSchedulerTest : public testing::Test { 119 class ResourceSchedulerTest : public testing::Test {
79 protected: 120 protected:
80 ResourceSchedulerTest() 121 ResourceSchedulerTest()
81 : message_loop_(MessageLoop::TYPE_IO), 122 : next_request_id_(0),
82 ui_thread_(BrowserThread::UI, &message_loop_) { 123 message_loop_(MessageLoop::TYPE_IO),
124 ui_thread_(BrowserThread::UI, &message_loop_),
125 io_thread_(BrowserThread::IO, &message_loop_) {
83 scheduler_.OnClientCreated(kChildId, kRouteId); 126 scheduler_.OnClientCreated(kChildId, kRouteId);
84 } 127 }
85 128
86 virtual ~ResourceSchedulerTest() { 129 virtual ~ResourceSchedulerTest() {
87 scheduler_.OnClientDeleted(kChildId, kRouteId); 130 scheduler_.OnClientDeleted(kChildId, kRouteId);
88 } 131 }
89 132
90 scoped_ptr<net::URLRequest> NewURLRequest(const char* url, 133 scoped_ptr<net::URLRequest> NewURLRequestWithRoute(
91 net::RequestPriority priority, 134 const char* url,
92 int route_id = kRouteId) { 135 net::RequestPriority priority,
136 int route_id) {
93 scoped_ptr<net::URLRequest> url_request( 137 scoped_ptr<net::URLRequest> url_request(
94 context_.CreateRequest(GURL(url), NULL)); 138 context_.CreateRequest(GURL(url), NULL));
95 url_request->SetPriority(priority); 139 url_request->SetPriority(priority);
96 ResourceRequestInfo::AllocateForTesting( 140 ResourceRequestInfoImpl* info = new ResourceRequestInfoImpl(
97 url_request.get(), ResourceType::SUB_RESOURCE, NULL, kChildId, 141 PROCESS_TYPE_RENDERER, // process_type
98 route_id); 142 kChildId, // child_id
143 route_id, // route_id
144 0, // origin_pid
145 ++next_request_id_, // request_id
146 false, // is_main_frame
147 0, // frame_id
148 false, // parent_is_main_frame
149 0, // parent_frame_id
150 ResourceType::SUB_RESOURCE, // resource_type
151 PAGE_TRANSITION_LINK, // transition_type
152 false, // is_download
153 false, // is_stream
154 true, // allow_download
155 false, // has_user_gesture
156 WebKit::WebReferrerPolicyDefault, // referrer_policy
157 NULL, // context
158 true); // is_async
159 info->AssociateWithRequest(url_request.get());
99 return url_request.Pass(); 160 return url_request.Pass();
100 } 161 }
101 162
102 TestRequest* NewRequest(const char* url, net::RequestPriority priority, 163 scoped_ptr<net::URLRequest> NewURLRequest(const char* url,
103 int route_id = kRouteId) { 164 net::RequestPriority priority) {
165 return NewURLRequestWithRoute(url, priority, kRouteId);
166 }
167
168 TestRequest* NewRequestWithRoute(const char* url,
169 net::RequestPriority priority,
170 int route_id) {
104 scoped_ptr<net::URLRequest> url_request( 171 scoped_ptr<net::URLRequest> url_request(
105 NewURLRequest(url, priority, route_id)); 172 NewURLRequestWithRoute(url, priority, route_id));
106 scoped_ptr<ResourceThrottle> throttle(scheduler_.ScheduleRequest( 173 scoped_ptr<ResourceThrottle> throttle(scheduler_.ScheduleRequest(
107 kChildId, route_id, url_request.get())); 174 kChildId, route_id, url_request.get()));
108 TestRequest* request = new TestRequest(throttle.Pass(), url_request.Pass()); 175 TestRequest* request = new TestRequest(throttle.Pass(), url_request.Pass());
109 request->Start(); 176 request->Start();
110 return request; 177 return request;
111 } 178 }
112 179
180 TestRequest* NewRequest(const char* url, net::RequestPriority priority) {
181 return NewRequestWithRoute(url, priority, kRouteId);
182 }
183
184 void ChangeRequestPriority(TestRequest* request,
185 net::RequestPriority new_priority) {
186 scoped_refptr<FakeResourceMessageFilter> filter(
187 new FakeResourceMessageFilter(kChildId));
188 const ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest(
189 request->url_request());
190 const GlobalRequestID& id = info->GetGlobalRequestID();
191 ResourceHostMsg_DidChangePriority msg(
192 kRouteId, id.request_id, new_priority);
193 bool ok = false;
194 rdh_.OnMessageReceived(msg, filter.get(), &ok);
195 EXPECT_TRUE(ok);
196 }
197
198 int next_request_id_;
113 MessageLoop message_loop_; 199 MessageLoop message_loop_;
114 BrowserThreadImpl ui_thread_; 200 BrowserThreadImpl ui_thread_;
201 BrowserThreadImpl io_thread_;
115 ResourceDispatcherHostImpl rdh_; 202 ResourceDispatcherHostImpl rdh_;
116 ResourceScheduler scheduler_; 203 ResourceScheduler scheduler_;
117 net::TestURLRequestContext context_; 204 net::TestURLRequestContext context_;
118 }; 205 };
119 206
120 TEST_F(ResourceSchedulerTest, OneIsolatedLowRequest) { 207 TEST_F(ResourceSchedulerTest, OneIsolatedLowRequest) {
121 scoped_ptr<TestRequest> request(NewRequest("http://host/1", net::LOWEST)); 208 scoped_ptr<TestRequest> request(NewRequest("http://host/1", net::LOWEST));
122 EXPECT_TRUE(request->started()); 209 EXPECT_TRUE(request->started());
123 } 210 }
124 211
(...skipping 19 matching lines...) Expand all
144 scheduler_.OnWillInsertBody(kChildId, kRouteId); 231 scheduler_.OnWillInsertBody(kChildId, kRouteId);
145 scheduler_.OnNavigate(kChildId, kRouteId); 232 scheduler_.OnNavigate(kChildId, kRouteId);
146 scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST)); 233 scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST));
147 scoped_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST)); 234 scoped_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
148 EXPECT_TRUE(high->started()); 235 EXPECT_TRUE(high->started());
149 EXPECT_FALSE(low->started()); 236 EXPECT_FALSE(low->started());
150 } 237 }
151 238
152 TEST_F(ResourceSchedulerTest, BackgroundRequestStartsImmediately) { 239 TEST_F(ResourceSchedulerTest, BackgroundRequestStartsImmediately) {
153 const int route_id = 0; // Indicates a background request. 240 const int route_id = 0; // Indicates a background request.
154 scoped_ptr<TestRequest> request(NewRequest("http://host/1", net::LOWEST, 241 scoped_ptr<TestRequest> request(NewRequestWithRoute("http://host/1",
155 route_id)); 242 net::LOWEST, route_id));
156 EXPECT_TRUE(request->started()); 243 EXPECT_TRUE(request->started());
157 } 244 }
158 245
159 TEST_F(ResourceSchedulerTest, StartRequestsWhenIdle) { 246 TEST_F(ResourceSchedulerTest, StartRequestsWhenIdle) {
160 scoped_ptr<TestRequest> high1(NewRequest("http://host/high1", net::HIGHEST)); 247 scoped_ptr<TestRequest> high1(NewRequest("http://host/high1", net::HIGHEST));
161 scoped_ptr<TestRequest> high2(NewRequest("http://host/high2", net::HIGHEST)); 248 scoped_ptr<TestRequest> high2(NewRequest("http://host/high2", net::HIGHEST));
162 scoped_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST)); 249 scoped_ptr<TestRequest> low(NewRequest("http://host/low", net::LOWEST));
163 EXPECT_TRUE(high1->started()); 250 EXPECT_TRUE(high1->started());
164 EXPECT_TRUE(high2->started()); 251 EXPECT_TRUE(high2->started());
165 EXPECT_FALSE(low->started()); 252 EXPECT_FALSE(low->started());
(...skipping 20 matching lines...) Expand all
186 scoped_ptr<TestRequest> low4(NewRequest("http://host/low4", net::LOWEST)); 273 scoped_ptr<TestRequest> low4(NewRequest("http://host/low4", net::LOWEST));
187 274
188 EXPECT_TRUE(high->started()); 275 EXPECT_TRUE(high->started());
189 EXPECT_FALSE(low2->started()); 276 EXPECT_FALSE(low2->started());
190 high.reset(); 277 high.reset();
191 EXPECT_TRUE(low1->started()); 278 EXPECT_TRUE(low1->started());
192 EXPECT_TRUE(low2->started()); 279 EXPECT_TRUE(low2->started());
193 EXPECT_TRUE(low4->started()); 280 EXPECT_TRUE(low4->started());
194 } 281 }
195 282
283 TEST_F(ResourceSchedulerTest, LimitedNumberOfDelayableRequestsInFlight) {
284 // We only load low priority resources if there's a body.
285 scheduler_.OnWillInsertBody(kChildId, kRouteId);
286
287 // Throw in one high priority request to make sure that's not a factor.
288 scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST));
289 EXPECT_TRUE(high->started());
290
291 const int kMaxNumDelayableRequestsPerClient = 10; // Should match the .cc.
292 ScopedVector<TestRequest> lows;
293 for (int i = 0; i < kMaxNumDelayableRequestsPerClient; ++i) {
294 string url = "http://host/low" + base::IntToString(i);
295 lows.push_back(NewRequest(url.c_str(), net::LOWEST));
296 EXPECT_TRUE(lows[i]->started());
297 }
298
299 scoped_ptr<TestRequest> last(NewRequest("http://host/last", net::LOWEST));
300 EXPECT_FALSE(last->started());
301 high.reset();
302 EXPECT_FALSE(last->started());
303 lows.erase(lows.begin());
304 EXPECT_TRUE(last->started());
305 }
306
307 TEST_F(ResourceSchedulerTest, RaisePriorityAndStart) {
308 // Dummy to enforce scheduling.
309 scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST));
310
311 scoped_ptr<TestRequest> request(NewRequest("http://host/req", net::LOWEST));
312 EXPECT_FALSE(request->started());
313
314 ChangeRequestPriority(request.get(), net::HIGHEST);
315 EXPECT_TRUE(request->started());
316 }
317
318 TEST_F(ResourceSchedulerTest, RaisePriorityInQueue) {
319 // Dummy to enforce scheduling.
320 scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST));
321
322 scoped_ptr<TestRequest> request(NewRequest("http://host/req", net::IDLE));
323 scoped_ptr<TestRequest> idle(NewRequest("http://host/idle", net::IDLE));
324 EXPECT_FALSE(request->started());
325 EXPECT_FALSE(idle->started());
326
327 ChangeRequestPriority(request.get(), net::LOWEST);
328 EXPECT_FALSE(request->started());
329 EXPECT_FALSE(idle->started());
330
331 const int kMaxNumDelayableRequestsPerClient = 10; // Should match the .cc.
332 ScopedVector<TestRequest> lows;
333 for (int i = 0; i < kMaxNumDelayableRequestsPerClient - 1; ++i) {
334 string url = "http://host/low" + base::IntToString(i);
335 lows.push_back(NewRequest(url.c_str(), net::LOWEST));
336 }
337
338 scheduler_.OnWillInsertBody(kChildId, kRouteId);
339 EXPECT_TRUE(request->started());
340 EXPECT_FALSE(idle->started());
341 }
342
343 TEST_F(ResourceSchedulerTest, LowerPriority) {
344 // Dummy to enforce scheduling.
345 scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST));
346
347 scoped_ptr<TestRequest> request(NewRequest("http://host/req", net::LOWEST));
348 scoped_ptr<TestRequest> idle(NewRequest("http://host/idle", net::IDLE));
349 EXPECT_FALSE(request->started());
350 EXPECT_FALSE(idle->started());
351
352 ChangeRequestPriority(request.get(), net::IDLE);
353 EXPECT_FALSE(request->started());
354 EXPECT_FALSE(idle->started());
355
356 const int kMaxNumDelayableRequestsPerClient = 10; // Should match the .cc.
357 ScopedVector<TestRequest> lows;
358 for (int i = 0; i < kMaxNumDelayableRequestsPerClient - 1; ++i) {
359 string url = "http://host/low" + base::IntToString(i);
360 lows.push_back(NewRequest(url.c_str(), net::LOWEST));
361 }
362
363 scheduler_.OnWillInsertBody(kChildId, kRouteId);
364 EXPECT_FALSE(request->started());
365 EXPECT_TRUE(idle->started());
366 }
367
368 TEST_F(ResourceSchedulerTest, ReprioritizedRequestGoesToBackOfQueue) {
369 // Dummy to enforce scheduling.
370 scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST));
371
372 scoped_ptr<TestRequest> request(NewRequest("http://host/req", net::LOWEST));
373 scoped_ptr<TestRequest> idle(NewRequest("http://host/idle", net::IDLE));
374 EXPECT_FALSE(request->started());
375 EXPECT_FALSE(idle->started());
376
377 const int kMaxNumDelayableRequestsPerClient = 10; // Should match the .cc.
378 ScopedVector<TestRequest> lows;
379 for (int i = 0; i < kMaxNumDelayableRequestsPerClient; ++i) {
380 string url = "http://host/low" + base::IntToString(i);
381 lows.push_back(NewRequest(url.c_str(), net::LOWEST));
382 }
383
384 ChangeRequestPriority(request.get(), net::IDLE);
385 EXPECT_FALSE(request->started());
386 EXPECT_FALSE(idle->started());
387
388 ChangeRequestPriority(request.get(), net::LOWEST);
389 EXPECT_FALSE(request->started());
390 EXPECT_FALSE(idle->started());
391
392 scheduler_.OnWillInsertBody(kChildId, kRouteId);
393 EXPECT_FALSE(request->started());
394 EXPECT_FALSE(idle->started());
395 }
396
196 } // unnamed namespace 397 } // unnamed namespace
197 398
198 } // namespace content 399 } // namespace content
OLDNEW
« no previous file with comments | « content/browser/loader/resource_scheduler.cc ('k') | no next file » | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698