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

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

Powered by Google App Engine
This is Rietveld 408576698