Chromium Code Reviews| Index: content/browser/loader/resource_scheduler_unittest.cc |
| diff --git a/content/browser/loader/resource_scheduler_unittest.cc b/content/browser/loader/resource_scheduler_unittest.cc |
| index be112414dd8e5d58a0bb2352e7f428407d3be06b..7cbf79e9a17d06b3567c205613f66dfcb1c3df81 100644 |
| --- a/content/browser/loader/resource_scheduler_unittest.cc |
| +++ b/content/browser/loader/resource_scheduler_unittest.cc |
| @@ -4,10 +4,15 @@ |
| #include "content/browser/loader/resource_scheduler.h" |
| +#include "base/memory/scoped_vector.h" |
| #include "base/message_loop.h" |
| +#include "base/strings/string_number_conversions.h" |
| #include "content/browser/browser_thread_impl.h" |
| #include "content/browser/loader/resource_dispatcher_host_impl.h" |
| +#include "content/browser/loader/resource_message_filter.h" |
| #include "content/browser/loader/resource_request_info_impl.h" |
| +#include "content/common/resource_messages.h" |
| +#include "content/public/browser/resource_context.h" |
| #include "content/public/browser/resource_controller.h" |
| #include "content/public/browser/resource_throttle.h" |
| #include "net/url_request/url_request.h" |
| @@ -42,6 +47,8 @@ class TestRequest : public ResourceController { |
| started_ = !deferred; |
| } |
| + const net::URLRequest* url_request() const { return url_request_.get(); } |
| + |
| protected: |
| // ResourceController interface: |
| virtual void Cancel() OVERRIDE {} |
| @@ -75,11 +82,46 @@ class CancelingTestRequest : public TestRequest { |
| scoped_ptr<TestRequest> request_to_cancel_; |
| }; |
| +class TestResourceContext : public ResourceContext { |
|
willchan no longer on Chromium
2013/03/19 20:53:53
In the future, I suggest you follow the normal con
James Simonsen
2013/03/19 23:00:46
Done.
|
| + private: |
| + virtual net::HostResolver* GetHostResolver() OVERRIDE { return NULL; } |
| + virtual net::URLRequestContext* GetRequestContext() OVERRIDE { return NULL; } |
| +}; |
| + |
| +class TestURLRequestContextSelector |
| + : public ResourceMessageFilter::URLRequestContextSelector { |
| + private: |
| + virtual net::URLRequestContext* GetRequestContext( |
| + ResourceType::Type) OVERRIDE { |
| + return NULL; |
| + } |
| +}; |
| + |
| +class TestResourceMessageFilter : public ResourceMessageFilter { |
| + public: |
| + TestResourceMessageFilter(int child_id) |
| + : ResourceMessageFilter(child_id, |
| + PROCESS_TYPE_RENDERER, |
| + &context_, |
| + NULL /* appcache_service */, |
| + NULL /* blob_storage_context */, |
| + NULL /* file_system_context */, |
| + new TestURLRequestContextSelector) { |
| + } |
| + |
| + private: |
| + virtual ~TestResourceMessageFilter() {} |
| + |
| + TestResourceContext context_; |
| +}; |
| + |
| class ResourceSchedulerTest : public testing::Test { |
| protected: |
| ResourceSchedulerTest() |
| - : message_loop_(MessageLoop::TYPE_IO), |
| - ui_thread_(BrowserThread::UI, &message_loop_) { |
| + : next_request_id_(0), |
| + message_loop_(MessageLoop::TYPE_IO), |
| + ui_thread_(BrowserThread::UI, &message_loop_), |
| + io_thread_(BrowserThread::IO, &message_loop_) { |
| scheduler_.OnClientCreated(kChildId, kRouteId); |
| } |
| @@ -93,9 +135,25 @@ class ResourceSchedulerTest : public testing::Test { |
| scoped_ptr<net::URLRequest> url_request( |
| context_.CreateRequest(GURL(url), NULL)); |
| url_request->set_priority(priority); |
| - ResourceRequestInfo::AllocateForTesting( |
| - url_request.get(), ResourceType::SUB_RESOURCE, NULL, kChildId, |
| - route_id); |
| + ResourceRequestInfoImpl* info = new ResourceRequestInfoImpl( |
| + PROCESS_TYPE_RENDERER, // process_type |
| + kChildId, // child_id |
| + route_id, // route_id |
| + 0, // origin_pid |
| + ++next_request_id_, // request_id |
| + false, // is_main_frame |
| + 0, // frame_id |
| + false, // parent_is_main_frame |
| + 0, // parent_frame_id |
| + ResourceType::SUB_RESOURCE, // resource_type |
| + PAGE_TRANSITION_LINK, // transition_type |
| + false, // is_download |
| + true, // allow_download |
| + false, // has_user_gesture |
| + WebKit::WebReferrerPolicyDefault, // referrer_policy |
| + NULL, // context |
| + true); // is_async |
| + info->AssociateWithRequest(url_request.get()); |
| return url_request.Pass(); |
| } |
| @@ -110,8 +168,24 @@ class ResourceSchedulerTest : public testing::Test { |
| return request; |
| } |
| + void ChangeRequestPriority(TestRequest* request, |
| + net::RequestPriority new_priority) { |
| + scoped_refptr<TestResourceMessageFilter> filter( |
| + new TestResourceMessageFilter(kChildId)); |
| + const ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest( |
| + request->url_request()); |
| + const GlobalRequestID& id = info->GetGlobalRequestID(); |
| + ResourceHostMsg_DidChangePriority msg( |
| + kRouteId, id.request_id, new_priority); |
| + bool ok = false; |
| + rdh_.OnMessageReceived(msg, filter.get(), &ok); |
| + EXPECT_TRUE(ok); |
| + } |
| + |
| + int next_request_id_; |
| MessageLoop message_loop_; |
| BrowserThreadImpl ui_thread_; |
| + BrowserThreadImpl io_thread_; |
| ResourceDispatcherHostImpl rdh_; |
| ResourceScheduler scheduler_; |
| net::TestURLRequestContext context_; |
| @@ -193,6 +267,91 @@ TEST_F(ResourceSchedulerTest, CancelOtherRequestsWhileResuming) { |
| EXPECT_TRUE(low4->started()); |
| } |
| +TEST_F(ResourceSchedulerTest, LimitedNumberOfLowPriorityRequestsInFlight) { |
| + // We only load low priority resources if there's a body. |
| + scheduler_.OnWillInsertBody(kChildId, kRouteId); |
| + |
| + // Throw in one high priority request to make sure that's not a factor. |
| + scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST)); |
| + EXPECT_TRUE(high->started()); |
| + |
| + const int kMaxNumLowPriorityRequestsPerClient = 10; // Should match the .cc. |
| + ScopedVector<TestRequest> lows; |
| + for (int i = 0; i < kMaxNumLowPriorityRequestsPerClient; ++i) { |
| + string url = "http://host/low" + base::IntToString(i); |
| + lows.push_back(NewRequest(url.c_str(), net::LOWEST)); |
| + EXPECT_TRUE(lows[i]->started()); |
| + } |
| + |
| + scoped_ptr<TestRequest> last(NewRequest("http://host/last", net::LOWEST)); |
| + EXPECT_FALSE(last->started()); |
| + high.reset(); |
| + EXPECT_FALSE(last->started()); |
| + lows.erase(lows.begin()); |
| + EXPECT_TRUE(last->started()); |
| +} |
| + |
| +TEST_F(ResourceSchedulerTest, RaisePriorityAndStart) { |
| + // Dummy to enforce scheduling. |
| + scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST)); |
| + |
| + scoped_ptr<TestRequest> request(NewRequest("http://host/req", net::LOWEST)); |
| + EXPECT_FALSE(request->started()); |
| + |
| + ChangeRequestPriority(request.get(), net::HIGHEST); |
| + EXPECT_TRUE(request->started()); |
| +} |
| + |
| +TEST_F(ResourceSchedulerTest, RaisePriorityInQueue) { |
| + // Dummy to enforce scheduling. |
| + scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST)); |
| + |
| + scoped_ptr<TestRequest> request(NewRequest("http://host/req", net::IDLE)); |
| + scoped_ptr<TestRequest> idle(NewRequest("http://host/idle", net::IDLE)); |
| + EXPECT_FALSE(request->started()); |
| + EXPECT_FALSE(idle->started()); |
| + |
| + ChangeRequestPriority(request.get(), net::LOWEST); |
| + EXPECT_FALSE(request->started()); |
| + EXPECT_FALSE(idle->started()); |
| + |
| + const int kMaxNumLowPriorityRequestsPerClient = 10; // Should match the .cc. |
| + ScopedVector<TestRequest> lows; |
| + for (int i = 0; i < kMaxNumLowPriorityRequestsPerClient - 1; ++i) { |
| + string url = "http://host/low" + base::IntToString(i); |
| + lows.push_back(NewRequest(url.c_str(), net::LOWEST)); |
| + } |
| + |
| + scheduler_.OnWillInsertBody(kChildId, kRouteId); |
| + EXPECT_TRUE(request->started()); |
| + EXPECT_FALSE(idle->started()); |
| +} |
| + |
| +TEST_F(ResourceSchedulerTest, LowerPriority) { |
| + // Dummy to enforce scheduling. |
| + scoped_ptr<TestRequest> high(NewRequest("http://host/high", net::HIGHEST)); |
| + |
| + scoped_ptr<TestRequest> request(NewRequest("http://host/req", net::LOWEST)); |
| + scoped_ptr<TestRequest> idle(NewRequest("http://host/idle", net::IDLE)); |
| + EXPECT_FALSE(request->started()); |
| + EXPECT_FALSE(idle->started()); |
| + |
| + ChangeRequestPriority(request.get(), net::IDLE); |
| + EXPECT_FALSE(request->started()); |
| + EXPECT_FALSE(idle->started()); |
| + |
| + const int kMaxNumLowPriorityRequestsPerClient = 10; // Should match the .cc. |
| + ScopedVector<TestRequest> lows; |
| + for (int i = 0; i < kMaxNumLowPriorityRequestsPerClient - 1; ++i) { |
| + string url = "http://host/low" + base::IntToString(i); |
| + lows.push_back(NewRequest(url.c_str(), net::LOWEST)); |
| + } |
| + |
| + scheduler_.OnWillInsertBody(kChildId, kRouteId); |
| + EXPECT_FALSE(request->started()); |
| + EXPECT_TRUE(idle->started()); |
| +} |
| + |
| } // unnamed namespace |
| } // namespace content |