| 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..750975579a37bdcf87678cb02213c17b24d440fe 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 {
|
| + 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
|
| + false); // 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
|
|
|