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

Unified Diff: content/browser/renderer_host/resource_dispatcher_host_unittest.cc

Issue 11414299: Add content/browser/loader/ for resource loading related classes. (Closed) Base URL: svn://svn.chromium.org/chrome/trunk/src/
Patch Set: Created 8 years 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 side-by-side diff with in-line comments
Download patch
Index: content/browser/renderer_host/resource_dispatcher_host_unittest.cc
===================================================================
--- content/browser/renderer_host/resource_dispatcher_host_unittest.cc (revision 171168)
+++ content/browser/renderer_host/resource_dispatcher_host_unittest.cc (working copy)
@@ -1,1958 +0,0 @@
-// Copyright (c) 2012 The Chromium Authors. All rights reserved.
-// Use of this source code is governed by a BSD-style license that can be
-// found in the LICENSE file.
-
-#include "content/browser/renderer_host/resource_dispatcher_host_impl.h"
-
-#include <vector>
-
-#include "base/bind.h"
-#include "base/file_path.h"
-#include "base/memory/scoped_vector.h"
-#include "base/message_loop.h"
-#include "base/process_util.h"
-#include "base/string_number_conversions.h"
-#include "base/string_split.h"
-#include "content/browser/browser_thread_impl.h"
-#include "content/browser/child_process_security_policy_impl.h"
-#include "content/browser/renderer_host/resource_dispatcher_host_impl.h"
-#include "content/browser/renderer_host/resource_message_filter.h"
-#include "content/common/child_process_host_impl.h"
-#include "content/common/resource_messages.h"
-#include "content/common/view_messages.h"
-#include "content/public/browser/global_request_id.h"
-#include "content/public/browser/resource_context.h"
-#include "content/public/browser/resource_dispatcher_host_delegate.h"
-#include "content/public/browser/resource_throttle.h"
-#include "content/public/common/resource_response.h"
-#include "content/public/test/test_browser_context.h"
-#include "content/test/test_content_browser_client.h"
-#include "net/base/net_errors.h"
-#include "net/base/upload_data.h"
-#include "net/http/http_util.h"
-#include "net/url_request/url_request.h"
-#include "net/url_request/url_request_context.h"
-#include "net/url_request/url_request_job.h"
-#include "net/url_request/url_request_simple_job.h"
-#include "net/url_request/url_request_test_job.h"
-#include "testing/gtest/include/gtest/gtest.h"
-#include "webkit/appcache/appcache_interfaces.h"
-
-// TODO(eroman): Write unit tests for SafeBrowsing that exercise
-// SafeBrowsingResourceHandler.
-
-namespace content {
-
-namespace {
-
-// Returns the resource response header structure for this request.
-void GetResponseHead(const std::vector<IPC::Message>& messages,
- ResourceResponseHead* response_head) {
- ASSERT_GE(messages.size(), 2U);
-
- // The first messages should be received response.
- ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
-
- PickleIterator iter(messages[0]);
- int request_id;
- ASSERT_TRUE(IPC::ReadParam(&messages[0], &iter, &request_id));
- ASSERT_TRUE(IPC::ReadParam(&messages[0], &iter, response_head));
-}
-
-void GenerateIPCMessage(
- scoped_refptr<ResourceMessageFilter> filter,
- scoped_ptr<IPC::Message> message) {
- bool msg_is_ok;
- ResourceDispatcherHostImpl::Get()->OnMessageReceived(
- *message, filter.get(), &msg_is_ok);
-}
-
-} // namespace
-
-static int RequestIDForMessage(const IPC::Message& msg) {
- int request_id = -1;
- switch (msg.type()) {
- case ResourceMsg_UploadProgress::ID:
- case ResourceMsg_ReceivedResponse::ID:
- case ResourceMsg_ReceivedRedirect::ID:
- case ResourceMsg_SetDataBuffer::ID:
- case ResourceMsg_DataReceived::ID:
- case ResourceMsg_RequestComplete::ID:
- request_id = IPC::MessageIterator(msg).NextInt();
- break;
- }
- return request_id;
-}
-
-static ResourceHostMsg_Request CreateResourceRequest(
- const char* method,
- ResourceType::Type type,
- const GURL& url) {
- ResourceHostMsg_Request request;
- request.method = std::string(method);
- request.url = url;
- request.first_party_for_cookies = url; // bypass third-party cookie blocking
- request.referrer_policy = WebKit::WebReferrerPolicyDefault;
- request.load_flags = 0;
- request.origin_pid = 0;
- request.resource_type = type;
- request.request_context = 0;
- request.appcache_host_id = appcache::kNoHostId;
- request.download_to_file = false;
- request.is_main_frame = true;
- request.frame_id = 0;
- request.parent_is_main_frame = false;
- request.parent_frame_id = -1;
- request.transition_type = PAGE_TRANSITION_LINK;
- request.allow_download = true;
- return request;
-}
-
-// Spin up the message loop to kick off the request.
-static void KickOffRequest() {
- MessageLoop::current()->RunUntilIdle();
-}
-
-// We may want to move this to a shared space if it is useful for something else
-class ResourceIPCAccumulator {
- public:
- void AddMessage(const IPC::Message& msg) {
- messages_.push_back(msg);
- }
-
- // This groups the messages by their request ID. The groups will be in order
- // that the first message for each request ID was received, and the messages
- // within the groups will be in the order that they appeared.
- // Note that this clears messages_.
- typedef std::vector< std::vector<IPC::Message> > ClassifiedMessages;
- void GetClassifiedMessages(ClassifiedMessages* msgs);
-
- private:
- std::vector<IPC::Message> messages_;
-};
-
-// This is very inefficient as a result of repeatedly extracting the ID, use
-// only for tests!
-void ResourceIPCAccumulator::GetClassifiedMessages(ClassifiedMessages* msgs) {
- while (!messages_.empty()) {
- // Ignore unknown message types as it is valid for code to generated other
- // IPCs as side-effects that we are not testing here.
- int cur_id = RequestIDForMessage(messages_[0]);
- if (cur_id != -1) {
- std::vector<IPC::Message> cur_requests;
- cur_requests.push_back(messages_[0]);
- // find all other messages with this ID
- for (int i = 1; i < static_cast<int>(messages_.size()); i++) {
- int id = RequestIDForMessage(messages_[i]);
- if (id == cur_id) {
- cur_requests.push_back(messages_[i]);
- messages_.erase(messages_.begin() + i);
- i--;
- }
- }
- msgs->push_back(cur_requests);
- }
- messages_.erase(messages_.begin());
- }
-}
-
-class MockURLRequestContextSelector
- : public ResourceMessageFilter::URLRequestContextSelector {
- public:
- explicit MockURLRequestContextSelector(
- net::URLRequestContext* request_context)
- : request_context_(request_context) {}
-
- virtual net::URLRequestContext* GetRequestContext(
- ResourceType::Type request_type) {
- return request_context_;
- }
-
- private:
- net::URLRequestContext* const request_context_;
-};
-
-// This class forwards the incoming messages to the ResourceDispatcherHostTest.
-// This is used to emulate different sub-processes, since this filter will
-// have a different ID than the original. For the test, we want all the incoming
-// messages to go to the same place, which is why this forwards.
-class ForwardingFilter : public ResourceMessageFilter {
- public:
- explicit ForwardingFilter(IPC::Sender* dest,
- ResourceContext* resource_context)
- : ResourceMessageFilter(
- ChildProcessHostImpl::GenerateChildProcessUniqueId(),
- PROCESS_TYPE_RENDERER,
- resource_context, NULL, NULL,
- new MockURLRequestContextSelector(
- resource_context->GetRequestContext())),
- dest_(dest) {
- OnChannelConnected(base::GetCurrentProcId());
- }
-
- // ResourceMessageFilter override
- virtual bool Send(IPC::Message* msg) {
- if (!dest_)
- return false;
- return dest_->Send(msg);
- }
-
- protected:
- virtual ~ForwardingFilter() {}
-
- private:
- IPC::Sender* dest_;
-
- DISALLOW_COPY_AND_ASSIGN(ForwardingFilter);
-};
-
-// This class is a variation on URLRequestTestJob in that it does
-// not complete start upon entry, only when specifically told to.
-class URLRequestTestDelayedStartJob : public net::URLRequestTestJob {
- public:
- URLRequestTestDelayedStartJob(net::URLRequest* request,
- net::NetworkDelegate* network_delegate)
- : net::URLRequestTestJob(request, network_delegate) {
- Init();
- }
- URLRequestTestDelayedStartJob(net::URLRequest* request,
- net::NetworkDelegate* network_delegate,
- bool auto_advance)
- : net::URLRequestTestJob(request, network_delegate, auto_advance) {
- Init();
- }
- URLRequestTestDelayedStartJob(net::URLRequest* request,
- net::NetworkDelegate* network_delegate,
- const std::string& response_headers,
- const std::string& response_data,
- bool auto_advance)
- : net::URLRequestTestJob(request,
- network_delegate,
- response_headers,
- response_data,
- auto_advance) {
- Init();
- }
-
- // Do nothing until you're told to.
- virtual void Start() {}
-
- // Finish starting a URL request whose job is an instance of
- // URLRequestTestDelayedStartJob. It is illegal to call this routine
- // with a URLRequest that does not use URLRequestTestDelayedStartJob.
- static void CompleteStart(net::URLRequest* request) {
- for (URLRequestTestDelayedStartJob* job = list_head_;
- job;
- job = job->next_) {
- if (job->request() == request) {
- job->net::URLRequestTestJob::Start();
- return;
- }
- }
- NOTREACHED();
- }
-
- static bool DelayedStartQueueEmpty() {
- return !list_head_;
- }
-
- static void ClearQueue() {
- if (list_head_) {
- LOG(ERROR)
- << "Unreleased entries on URLRequestTestDelayedStartJob delay queue"
- << "; may result in leaks.";
- list_head_ = NULL;
- }
- }
-
- protected:
- virtual ~URLRequestTestDelayedStartJob() {
- for (URLRequestTestDelayedStartJob** job = &list_head_; *job;
- job = &(*job)->next_) {
- if (*job == this) {
- *job = (*job)->next_;
- return;
- }
- }
- NOTREACHED();
- }
-
- private:
- void Init() {
- next_ = list_head_;
- list_head_ = this;
- }
-
- static URLRequestTestDelayedStartJob* list_head_;
- URLRequestTestDelayedStartJob* next_;
-};
-
-URLRequestTestDelayedStartJob*
-URLRequestTestDelayedStartJob::list_head_ = NULL;
-
-// This class is a variation on URLRequestTestJob in that it
-// returns IO_pending errors before every read, not just the first one.
-class URLRequestTestDelayedCompletionJob : public net::URLRequestTestJob {
- public:
- URLRequestTestDelayedCompletionJob(net::URLRequest* request,
- net::NetworkDelegate* network_delegate)
- : net::URLRequestTestJob(request, network_delegate) {}
- URLRequestTestDelayedCompletionJob(net::URLRequest* request,
- net::NetworkDelegate* network_delegate,
- bool auto_advance)
- : net::URLRequestTestJob(request, network_delegate, auto_advance) {}
- URLRequestTestDelayedCompletionJob(net::URLRequest* request,
- net::NetworkDelegate* network_delegate,
- const std::string& response_headers,
- const std::string& response_data,
- bool auto_advance)
- : net::URLRequestTestJob(request,
- network_delegate,
- response_headers,
- response_data,
- auto_advance) {}
-
- protected:
- ~URLRequestTestDelayedCompletionJob() {}
-
- private:
- virtual bool NextReadAsync() OVERRIDE { return true; }
-};
-
-class URLRequestBigJob : public net::URLRequestSimpleJob {
- public:
- URLRequestBigJob(net::URLRequest* request,
- net::NetworkDelegate* network_delegate)
- : net::URLRequestSimpleJob(request, network_delegate) {
- }
-
- virtual int GetData(std::string* mime_type,
- std::string* charset,
- std::string* data,
- const net::CompletionCallback& callback) const OVERRIDE {
- *mime_type = "text/plain";
- *charset = "UTF-8";
-
- std::string text;
- int count;
- if (!ParseURL(request_->url(), &text, &count))
- return net::ERR_INVALID_URL;
-
- data->reserve(text.size() * count);
- for (int i = 0; i < count; ++i)
- data->append(text);
-
- return net::OK;
- }
-
- private:
- virtual ~URLRequestBigJob() {}
-
- // big-job:substring,N
- static bool ParseURL(const GURL& url, std::string* text, int* count) {
- std::vector<std::string> parts;
- base::SplitString(url.path(), ',', &parts);
-
- if (parts.size() != 2)
- return false;
-
- *text = parts[0];
- return base::StringToInt(parts[1], count);
- }
-};
-
-// Associated with an URLRequest to determine if the URLRequest gets deleted.
-class TestUserData : public base::SupportsUserData::Data {
- public:
- explicit TestUserData(bool* was_deleted)
- : was_deleted_(was_deleted) {
- }
-
- ~TestUserData() {
- *was_deleted_ = true;
- }
-
- private:
- bool* was_deleted_;
-};
-
-class TransfersAllNavigationsContentBrowserClient
- : public TestContentBrowserClient {
- public:
- virtual bool ShouldSwapProcessesForRedirect(ResourceContext* resource_context,
- const GURL& current_url,
- const GURL& new_url) {
- return true;
- }
-};
-
-enum GenericResourceThrottleFlags {
- NONE = 0,
- DEFER_STARTING_REQUEST = 1 << 0,
- DEFER_PROCESSING_RESPONSE = 1 << 1,
- CANCEL_BEFORE_START = 1 << 2
-};
-
-// Throttle that tracks the current throttle blocking a request. Only one
-// can throttle any request at a time.
-class GenericResourceThrottle : public ResourceThrottle {
- public:
- // The value is used to indicate that the throttle should not provide
- // a error code when cancelling a request. net::OK is used, because this
- // is not an error code.
- static const int USE_DEFAULT_CANCEL_ERROR_CODE = net::OK;
-
- GenericResourceThrottle(int flags, int code)
- : flags_(flags),
- error_code_for_cancellation_(code) {
- }
-
- virtual ~GenericResourceThrottle() {
- if (active_throttle_ == this)
- active_throttle_ = NULL;
- }
-
- // ResourceThrottle implementation:
- virtual void WillStartRequest(bool* defer) OVERRIDE {
- ASSERT_EQ(NULL, active_throttle_);
- if (flags_ & DEFER_STARTING_REQUEST) {
- active_throttle_ = this;
- *defer = true;
- }
-
- if (flags_ & CANCEL_BEFORE_START) {
- if (error_code_for_cancellation_ == USE_DEFAULT_CANCEL_ERROR_CODE) {
- controller()->Cancel();
- } else {
- controller()->CancelWithError(error_code_for_cancellation_);
- }
- }
- }
-
- virtual void WillProcessResponse(bool* defer) OVERRIDE {
- ASSERT_EQ(NULL, active_throttle_);
- if (flags_ & DEFER_PROCESSING_RESPONSE) {
- active_throttle_ = this;
- *defer = true;
- }
- }
-
- void Resume() {
- ASSERT_TRUE(this == active_throttle_);
- active_throttle_ = NULL;
- controller()->Resume();
- }
-
- static GenericResourceThrottle* active_throttle() {
- return active_throttle_;
- }
-
- private:
- int flags_; // bit-wise union of GenericResourceThrottleFlags.
- int error_code_for_cancellation_;
-
- // The currently active throttle, if any.
- static GenericResourceThrottle* active_throttle_;
-};
-// static
-GenericResourceThrottle* GenericResourceThrottle::active_throttle_ = NULL;
-
-class TestResourceDispatcherHostDelegate
- : public ResourceDispatcherHostDelegate {
- public:
- TestResourceDispatcherHostDelegate()
- : create_two_throttles_(false),
- flags_(NONE),
- error_code_for_cancellation_(
- GenericResourceThrottle::USE_DEFAULT_CANCEL_ERROR_CODE) {
- }
-
- void set_url_request_user_data(base::SupportsUserData::Data* user_data) {
- user_data_.reset(user_data);
- }
-
- void set_flags(int value) {
- flags_ = value;
- }
-
- void set_error_code_for_cancellation(int code) {
- error_code_for_cancellation_ = code;
- }
-
- void set_create_two_throttles(bool create_two_throttles) {
- create_two_throttles_ = create_two_throttles;
- }
-
- // ResourceDispatcherHostDelegate implementation:
-
- virtual void RequestBeginning(
- net::URLRequest* request,
- ResourceContext* resource_context,
- appcache::AppCacheService* appcache_service,
- ResourceType::Type resource_type,
- int child_id,
- int route_id,
- bool is_continuation_of_transferred_request,
- ScopedVector<ResourceThrottle>* throttles) OVERRIDE {
- if (user_data_.get()) {
- const void* key = user_data_.get();
- request->SetUserData(key, user_data_.release());
- }
-
- if (flags_ != NONE) {
- throttles->push_back(new GenericResourceThrottle(
- flags_, error_code_for_cancellation_));
- if (create_two_throttles_)
- throttles->push_back(new GenericResourceThrottle(
- flags_, error_code_for_cancellation_));
- }
- }
-
- private:
- bool create_two_throttles_;
- int flags_;
- int error_code_for_cancellation_;
- scoped_ptr<base::SupportsUserData::Data> user_data_;
-};
-
-class ResourceDispatcherHostTest : public testing::Test,
- public IPC::Sender {
- public:
- ResourceDispatcherHostTest()
- : ui_thread_(BrowserThread::UI, &message_loop_),
- file_thread_(BrowserThread::FILE_USER_BLOCKING, &message_loop_),
- cache_thread_(BrowserThread::CACHE, &message_loop_),
- io_thread_(BrowserThread::IO, &message_loop_),
- old_factory_(NULL),
- resource_type_(ResourceType::SUB_RESOURCE),
- send_data_received_acks_(false) {
- browser_context_.reset(new TestBrowserContext());
- BrowserContext::EnsureResourceContextInitialized(browser_context_.get());
- message_loop_.RunUntilIdle();
- filter_ = new ForwardingFilter(
- this, browser_context_->GetResourceContext());
- }
- // IPC::Sender implementation
- virtual bool Send(IPC::Message* msg) {
- accum_.AddMessage(*msg);
-
- if (send_data_received_acks_ &&
- msg->type() == ResourceMsg_DataReceived::ID) {
- GenerateDataReceivedACK(*msg);
- }
-
- delete msg;
- return true;
- }
-
- protected:
- // testing::Test
- virtual void SetUp() {
- DCHECK(!test_fixture_);
- test_fixture_ = this;
- ChildProcessSecurityPolicyImpl::GetInstance()->Add(0);
- net::URLRequest::Deprecated::RegisterProtocolFactory(
- "test",
- &ResourceDispatcherHostTest::Factory);
- EnsureTestSchemeIsAllowed();
- delay_start_ = false;
- delay_complete_ = false;
- url_request_jobs_created_count_ = 0;
- }
-
- virtual void TearDown() {
- net::URLRequest::Deprecated::RegisterProtocolFactory("test", NULL);
- if (!scheme_.empty())
- net::URLRequest::Deprecated::RegisterProtocolFactory(
- scheme_, old_factory_);
-
- EXPECT_TRUE(URLRequestTestDelayedStartJob::DelayedStartQueueEmpty());
- URLRequestTestDelayedStartJob::ClearQueue();
-
- DCHECK(test_fixture_ == this);
- test_fixture_ = NULL;
-
- host_.Shutdown();
-
- ChildProcessSecurityPolicyImpl::GetInstance()->Remove(0);
-
- // Flush the message loop to make application verifiers happy.
- if (ResourceDispatcherHostImpl::Get())
- ResourceDispatcherHostImpl::Get()->CancelRequestsForContext(
- browser_context_->GetResourceContext());
- browser_context_.reset();
- message_loop_.RunUntilIdle();
- }
-
- // Creates a request using the current test object as the filter.
- void MakeTestRequest(int render_view_id,
- int request_id,
- const GURL& url);
-
- // Generates a request using the given filter. This will probably be a
- // ForwardingFilter.
- void MakeTestRequest(ResourceMessageFilter* filter,
- int render_view_id,
- int request_id,
- const GURL& url);
-
- void CancelRequest(int request_id);
-
- void CompleteStartRequest(int request_id);
- void CompleteStartRequest(ResourceMessageFilter* filter, int request_id);
-
- void EnsureSchemeIsAllowed(const std::string& scheme) {
- ChildProcessSecurityPolicyImpl* policy =
- ChildProcessSecurityPolicyImpl::GetInstance();
- if (!policy->IsWebSafeScheme(scheme))
- policy->RegisterWebSafeScheme(scheme);
- }
-
- void EnsureTestSchemeIsAllowed() {
- EnsureSchemeIsAllowed("test");
- }
-
- // Sets a particular response for any request from now on. To switch back to
- // the default bahavior, pass an empty |headers|. |headers| should be raw-
- // formatted (NULLs instead of EOLs).
- void SetResponse(const std::string& headers, const std::string& data) {
- response_headers_ = net::HttpUtil::AssembleRawHeaders(headers.data(),
- headers.size());
- response_data_ = data;
- }
- void SetResponse(const std::string& headers) {
- SetResponse(headers, std::string());
- }
-
- // Sets a particular resource type for any request from now on.
- void SetResourceType(ResourceType::Type type) {
- resource_type_ = type;
- }
-
- void SendDataReceivedACKs(bool send_acks) {
- send_data_received_acks_ = send_acks;
- }
-
- // Intercepts requests for the given protocol.
- void HandleScheme(const std::string& scheme) {
- DCHECK(scheme_.empty());
- DCHECK(!old_factory_);
- scheme_ = scheme;
- old_factory_ = net::URLRequest::Deprecated::RegisterProtocolFactory(
- scheme_, &ResourceDispatcherHostTest::Factory);
- EnsureSchemeIsAllowed(scheme);
- }
-
- // Our own net::URLRequestJob factory.
- static net::URLRequestJob* Factory(net::URLRequest* request,
- net::NetworkDelegate* network_delegate,
- const std::string& scheme) {
- url_request_jobs_created_count_++;
- if (test_fixture_->response_headers_.empty()) {
- if (delay_start_) {
- return new URLRequestTestDelayedStartJob(request, network_delegate);
- } else if (delay_complete_) {
- return new URLRequestTestDelayedCompletionJob(request,
- network_delegate);
- } else if (scheme == "big-job") {
- return new URLRequestBigJob(request, network_delegate);
- } else {
- return new net::URLRequestTestJob(request, network_delegate);
- }
- } else {
- if (delay_start_) {
- return new URLRequestTestDelayedStartJob(
- request, network_delegate,
- test_fixture_->response_headers_, test_fixture_->response_data_,
- false);
- } else if (delay_complete_) {
- return new URLRequestTestDelayedCompletionJob(
- request, network_delegate,
- test_fixture_->response_headers_, test_fixture_->response_data_,
- false);
- } else {
- return new net::URLRequestTestJob(
- request, network_delegate,
- test_fixture_->response_headers_, test_fixture_->response_data_,
- false);
- }
- }
- }
-
- void SetDelayedStartJobGeneration(bool delay_job_start) {
- delay_start_ = delay_job_start;
- }
-
- void SetDelayedCompleteJobGeneration(bool delay_job_complete) {
- delay_complete_ = delay_job_complete;
- }
-
- void GenerateDataReceivedACK(const IPC::Message& msg) {
- EXPECT_EQ(ResourceMsg_DataReceived::ID, msg.type());
-
- int request_id = IPC::MessageIterator(msg).NextInt();
- scoped_ptr<IPC::Message> ack(
- new ResourceHostMsg_DataReceived_ACK(msg.routing_id(), request_id));
-
- MessageLoop::current()->PostTask(
- FROM_HERE,
- base::Bind(&GenerateIPCMessage, filter_, base::Passed(&ack)));
- }
-
- MessageLoopForIO message_loop_;
- BrowserThreadImpl ui_thread_;
- BrowserThreadImpl file_thread_;
- BrowserThreadImpl cache_thread_;
- BrowserThreadImpl io_thread_;
- scoped_ptr<TestBrowserContext> browser_context_;
- scoped_refptr<ForwardingFilter> filter_;
- ResourceDispatcherHostImpl host_;
- ResourceIPCAccumulator accum_;
- std::string response_headers_;
- std::string response_data_;
- std::string scheme_;
- net::URLRequest::ProtocolFactory* old_factory_;
- ResourceType::Type resource_type_;
- bool send_data_received_acks_;
- static ResourceDispatcherHostTest* test_fixture_;
- static bool delay_start_;
- static bool delay_complete_;
- static int url_request_jobs_created_count_;
-};
-// Static.
-ResourceDispatcherHostTest* ResourceDispatcherHostTest::test_fixture_ = NULL;
-bool ResourceDispatcherHostTest::delay_start_ = false;
-bool ResourceDispatcherHostTest::delay_complete_ = false;
-int ResourceDispatcherHostTest::url_request_jobs_created_count_ = 0;
-
-void ResourceDispatcherHostTest::MakeTestRequest(int render_view_id,
- int request_id,
- const GURL& url) {
- MakeTestRequest(filter_.get(), render_view_id, request_id, url);
-}
-
-void ResourceDispatcherHostTest::MakeTestRequest(
- ResourceMessageFilter* filter,
- int render_view_id,
- int request_id,
- const GURL& url) {
- ResourceHostMsg_Request request =
- CreateResourceRequest("GET", resource_type_, url);
- ResourceHostMsg_RequestResource msg(render_view_id, request_id, request);
- bool msg_was_ok;
- host_.OnMessageReceived(msg, filter, &msg_was_ok);
- KickOffRequest();
-}
-
-void ResourceDispatcherHostTest::CancelRequest(int request_id) {
- host_.CancelRequest(filter_->child_id(), request_id, false);
-}
-
-void ResourceDispatcherHostTest::CompleteStartRequest(int request_id) {
- CompleteStartRequest(filter_, request_id);
-}
-
-void ResourceDispatcherHostTest::CompleteStartRequest(
- ResourceMessageFilter* filter,
- int request_id) {
- GlobalRequestID gid(filter->child_id(), request_id);
- net::URLRequest* req = host_.GetURLRequest(gid);
- EXPECT_TRUE(req);
- if (req)
- URLRequestTestDelayedStartJob::CompleteStart(req);
-}
-
-void CheckSuccessfulRequest(const std::vector<IPC::Message>& messages,
- const std::string& reference_data) {
- // A successful request will have received 4 messages:
- // ReceivedResponse (indicates headers received)
- // SetDataBuffer (contains shared memory handle)
- // DataReceived (data offset and length into shared memory)
- // RequestComplete (request is done)
- //
- // This function verifies that we received 4 messages and that they
- // are appropriate.
- ASSERT_EQ(4U, messages.size());
-
- // The first messages should be received response
- ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type());
-
- ASSERT_EQ(ResourceMsg_SetDataBuffer::ID, messages[1].type());
-
- PickleIterator iter(messages[1]);
- int request_id;
- ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &request_id));
- base::SharedMemoryHandle shm_handle;
- ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &shm_handle));
- int shm_size;
- ASSERT_TRUE(IPC::ReadParam(&messages[1], &iter, &shm_size));
-
- // Followed by the data, currently we only do the data in one chunk, but
- // should probably test multiple chunks later
- ASSERT_EQ(ResourceMsg_DataReceived::ID, messages[2].type());
-
- PickleIterator iter2(messages[2]);
- ASSERT_TRUE(IPC::ReadParam(&messages[2], &iter2, &request_id));
- int data_offset;
- ASSERT_TRUE(IPC::ReadParam(&messages[2], &iter2, &data_offset));
- int data_length;
- ASSERT_TRUE(IPC::ReadParam(&messages[2], &iter2, &data_length));
-
- ASSERT_EQ(reference_data.size(), static_cast<size_t>(data_length));
- ASSERT_GE(shm_size, data_length);
-
- base::SharedMemory shared_mem(shm_handle, true); // read only
- shared_mem.Map(data_length);
- const char* data = static_cast<char*>(shared_mem.memory()) + data_offset;
- ASSERT_EQ(0, memcmp(reference_data.c_str(), data, data_length));
-
- // The last message should be all data received.
- ASSERT_EQ(ResourceMsg_RequestComplete::ID, messages[3].type());
-}
-
-// Tests whether many messages get dispatched properly.
-TEST_F(ResourceDispatcherHostTest, TestMany) {
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-
- MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
- MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
- MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
-
- // flush all the pending requests
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
-
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-
- // sorts out all the messages we saw by request
- ResourceIPCAccumulator::ClassifiedMessages msgs;
- accum_.GetClassifiedMessages(&msgs);
-
- // there are three requests, so we should have gotten them classified as such
- ASSERT_EQ(3U, msgs.size());
-
- CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
- CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_2());
- CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3());
-}
-
-void CheckCancelledRequestCompleteMessage(const IPC::Message& message) {
- ASSERT_EQ(ResourceMsg_RequestComplete::ID, message.type());
-
- int request_id;
- int error_code;
-
- PickleIterator iter(message);
- ASSERT_TRUE(IPC::ReadParam(&message, &iter, &request_id));
- ASSERT_TRUE(IPC::ReadParam(&message, &iter, &error_code));
-
- EXPECT_EQ(net::ERR_ABORTED, error_code);
-}
-
-// Tests whether messages get canceled properly. We issue three requests,
-// cancel one of them, and make sure that each sent the proper notifications.
-TEST_F(ResourceDispatcherHostTest, Cancel) {
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-
- MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
- MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
- MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
- CancelRequest(2);
-
- // flush all the pending requests
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
- MessageLoop::current()->RunUntilIdle();
-
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-
- ResourceIPCAccumulator::ClassifiedMessages msgs;
- accum_.GetClassifiedMessages(&msgs);
-
- // there are three requests, so we should have gotten them classified as such
- ASSERT_EQ(3U, msgs.size());
-
- CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
- CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3());
-
- // Check that request 2 got canceled.
- ASSERT_EQ(2U, msgs[1].size());
- ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[1][0].type());
- CheckCancelledRequestCompleteMessage(msgs[1][1]);
-}
-
-TEST_F(ResourceDispatcherHostTest, CancelWhileStartIsDeferred) {
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-
- bool was_deleted = false;
-
- // Arrange to have requests deferred before starting.
- TestResourceDispatcherHostDelegate delegate;
- delegate.set_flags(DEFER_STARTING_REQUEST);
- delegate.set_url_request_user_data(new TestUserData(&was_deleted));
- host_.SetDelegate(&delegate);
-
- MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
- CancelRequest(1);
-
- // Our TestResourceThrottle should not have been deleted yet. This is to
- // ensure that destruction of the URLRequest happens asynchronously to
- // calling CancelRequest.
- EXPECT_FALSE(was_deleted);
-
- // flush all the pending requests
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
- MessageLoop::current()->RunUntilIdle();
-
- EXPECT_TRUE(was_deleted);
-
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-}
-
-// Tests if cancel is called in ResourceThrottle::WillStartRequest, then the
-// URLRequest will not be started.
-TEST_F(ResourceDispatcherHostTest, CancelInResourceThrottleWillStartRequest) {
- TestResourceDispatcherHostDelegate delegate;
- delegate.set_flags(CANCEL_BEFORE_START);
- host_.SetDelegate(&delegate);
-
- MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
-
- // flush all the pending requests
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
- MessageLoop::current()->RunUntilIdle();
-
- ResourceIPCAccumulator::ClassifiedMessages msgs;
- accum_.GetClassifiedMessages(&msgs);
-
- // Check that request got canceled.
- ASSERT_EQ(1U, msgs[0].size());
- CheckCancelledRequestCompleteMessage(msgs[0][0]);
-
- // Make sure URLRequest is never started.
- EXPECT_EQ(0, url_request_jobs_created_count_);
-}
-
-TEST_F(ResourceDispatcherHostTest, PausedStartError) {
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-
- // Arrange to have requests deferred before processing response headers.
- TestResourceDispatcherHostDelegate delegate;
- delegate.set_flags(DEFER_PROCESSING_RESPONSE);
- host_.SetDelegate(&delegate);
-
- SetDelayedStartJobGeneration(true);
- MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_error());
- CompleteStartRequest(1);
-
- // flush all the pending requests
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
- MessageLoop::current()->RunUntilIdle();
-
- EXPECT_EQ(0, host_.pending_requests());
-}
-
-TEST_F(ResourceDispatcherHostTest, ThrottleAndResumeTwice) {
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-
- // Arrange to have requests deferred before starting.
- TestResourceDispatcherHostDelegate delegate;
- delegate.set_flags(DEFER_STARTING_REQUEST);
- delegate.set_create_two_throttles(true);
- host_.SetDelegate(&delegate);
-
- // Make sure the first throttle blocked the request, and then resume.
- MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
- GenericResourceThrottle* first_throttle =
- GenericResourceThrottle::active_throttle();
- ASSERT_TRUE(first_throttle);
- first_throttle->Resume();
-
- // Make sure the second throttle blocked the request, and then resume.
- ASSERT_TRUE(GenericResourceThrottle::active_throttle());
- ASSERT_NE(first_throttle, GenericResourceThrottle::active_throttle());
- GenericResourceThrottle::active_throttle()->Resume();
-
- ASSERT_FALSE(GenericResourceThrottle::active_throttle());
-
- // The request is started asynchronously.
- MessageLoop::current()->RunUntilIdle();
-
- // Flush all the pending requests.
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
-
- EXPECT_EQ(0, host_.pending_requests());
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id()));
-
- // Make sure the request completed successfully.
- ResourceIPCAccumulator::ClassifiedMessages msgs;
- accum_.GetClassifiedMessages(&msgs);
- ASSERT_EQ(1U, msgs.size());
- CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
-}
-
-
-// Tests that the delegate can cancel a request and provide a error code.
-TEST_F(ResourceDispatcherHostTest, CancelInDelegate) {
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-
- TestResourceDispatcherHostDelegate delegate;
- delegate.set_flags(CANCEL_BEFORE_START);
- delegate.set_error_code_for_cancellation(net::ERR_ACCESS_DENIED);
- host_.SetDelegate(&delegate);
-
- MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
- // The request will get cancelled by the throttle.
-
- // flush all the pending requests
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
- MessageLoop::current()->RunUntilIdle();
-
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-
- ResourceIPCAccumulator::ClassifiedMessages msgs;
- accum_.GetClassifiedMessages(&msgs);
-
- // Check the cancellation
- ASSERT_EQ(1U, msgs.size());
- ASSERT_EQ(1U, msgs[0].size());
- ASSERT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type());
-
- int request_id;
- int error_code;
-
- PickleIterator iter(msgs[0][0]);
- ASSERT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &request_id));
- ASSERT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &error_code));
-
- EXPECT_EQ(net::ERR_ACCESS_DENIED, error_code);
-}
-
-// The host delegate acts as a second one so we can have some requests
-// pending and some canceled.
-class TestFilter : public ForwardingFilter {
- public:
- explicit TestFilter(ResourceContext* resource_context)
- : ForwardingFilter(NULL, resource_context),
- has_canceled_(false),
- received_after_canceled_(0) {
- }
-
- // ForwardingFilter override
- virtual bool Send(IPC::Message* msg) OVERRIDE {
- // no messages should be received when the process has been canceled
- if (has_canceled_)
- received_after_canceled_++;
- delete msg;
- return true;
- }
-
- bool has_canceled_;
- int received_after_canceled_;
-
- private:
- virtual ~TestFilter() {}
-};
-
-// Tests CancelRequestsForProcess
-TEST_F(ResourceDispatcherHostTest, TestProcessCancel) {
- scoped_refptr<TestFilter> test_filter = new TestFilter(
- browser_context_->GetResourceContext());
-
- // request 1 goes to the test delegate
- ResourceHostMsg_Request request = CreateResourceRequest(
- "GET", ResourceType::SUB_RESOURCE, net::URLRequestTestJob::test_url_1());
-
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-
- MakeTestRequest(test_filter.get(), 0, 1,
- net::URLRequestTestJob::test_url_1());
-
- // request 2 goes to us
- MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2());
-
- // request 3 goes to the test delegate
- MakeTestRequest(test_filter.get(), 0, 3,
- net::URLRequestTestJob::test_url_3());
-
- // Make sure all requests have finished stage one. test_url_1 will have
- // finished.
- MessageLoop::current()->RunUntilIdle();
-
- // TODO(mbelshe):
- // Now that the async IO path is in place, the IO always completes on the
- // initial call; so the requests have already completed. This basically
- // breaks the whole test.
- //EXPECT_EQ(3, host_.pending_requests());
-
- // Process each request for one level so one callback is called.
- for (int i = 0; i < 2; i++)
- EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
-
- // Cancel the requests to the test process.
- host_.CancelRequestsForProcess(filter_->child_id());
- test_filter->has_canceled_ = true;
-
- // Flush all the pending requests.
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
-
- EXPECT_EQ(0, host_.pending_requests());
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id()));
-
- // The test delegate should not have gotten any messages after being canceled.
- ASSERT_EQ(0, test_filter->received_after_canceled_);
-
- // We should have gotten exactly one result.
- ResourceIPCAccumulator::ClassifiedMessages msgs;
- accum_.GetClassifiedMessages(&msgs);
- ASSERT_EQ(1U, msgs.size());
- CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
-}
-
-// Tests blocking and resuming requests.
-TEST_F(ResourceDispatcherHostTest, TestBlockingResumingRequests) {
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id()));
-
- host_.BlockRequestsForRoute(filter_->child_id(), 1);
- host_.BlockRequestsForRoute(filter_->child_id(), 2);
- host_.BlockRequestsForRoute(filter_->child_id(), 3);
-
- MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
- MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
- MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
- MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
- MakeTestRequest(2, 5, net::URLRequestTestJob::test_url_2());
- MakeTestRequest(3, 6, net::URLRequestTestJob::test_url_3());
-
- // Flush all the pending requests
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
-
- // Sort out all the messages we saw by request
- ResourceIPCAccumulator::ClassifiedMessages msgs;
- accum_.GetClassifiedMessages(&msgs);
-
- // All requests but the 2 for the RVH 0 should have been blocked.
- ASSERT_EQ(2U, msgs.size());
-
- CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
- CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
-
- // Resume requests for RVH 1 and flush pending requests.
- host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 1);
- KickOffRequest();
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
-
- msgs.clear();
- accum_.GetClassifiedMessages(&msgs);
- ASSERT_EQ(2U, msgs.size());
- CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
- CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_1());
-
- // Test that new requests are not blocked for RVH 1.
- MakeTestRequest(1, 7, net::URLRequestTestJob::test_url_1());
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
- msgs.clear();
- accum_.GetClassifiedMessages(&msgs);
- ASSERT_EQ(1U, msgs.size());
- CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
-
- // Now resumes requests for all RVH (2 and 3).
- host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 2);
- host_.ResumeBlockedRequestsForRoute(filter_->child_id(), 3);
- KickOffRequest();
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
-
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id()));
-
- msgs.clear();
- accum_.GetClassifiedMessages(&msgs);
- ASSERT_EQ(2U, msgs.size());
- CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2());
- CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
-}
-
-// Tests blocking and canceling requests.
-TEST_F(ResourceDispatcherHostTest, TestBlockingCancelingRequests) {
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id()));
-
- host_.BlockRequestsForRoute(filter_->child_id(), 1);
-
- MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1());
- MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2());
- MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3());
- MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1());
-
- // Flush all the pending requests.
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
-
- // Sort out all the messages we saw by request.
- ResourceIPCAccumulator::ClassifiedMessages msgs;
- accum_.GetClassifiedMessages(&msgs);
-
- // The 2 requests for the RVH 0 should have been processed.
- ASSERT_EQ(2U, msgs.size());
-
- CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
- CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
-
- // Cancel requests for RVH 1.
- host_.CancelBlockedRequestsForRoute(filter_->child_id(), 1);
- KickOffRequest();
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
-
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id()));
-
- msgs.clear();
- accum_.GetClassifiedMessages(&msgs);
- ASSERT_EQ(0U, msgs.size());
-}
-
-// Tests that blocked requests are canceled if their associated process dies.
-TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) {
- // This second filter is used to emulate a second process.
- scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
- this, browser_context_->GetResourceContext());
-
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id()));
- EXPECT_EQ(0,
- host_.GetOutstandingRequestsMemoryCost(second_filter->child_id()));
-
- host_.BlockRequestsForRoute(second_filter->child_id(), 0);
-
- MakeTestRequest(filter_.get(), 0, 1, net::URLRequestTestJob::test_url_1());
- MakeTestRequest(second_filter.get(), 0, 2,
- net::URLRequestTestJob::test_url_2());
- MakeTestRequest(filter_.get(), 0, 3, net::URLRequestTestJob::test_url_3());
- MakeTestRequest(second_filter.get(), 0, 4,
- net::URLRequestTestJob::test_url_1());
-
- // Simulate process death.
- host_.CancelRequestsForProcess(second_filter->child_id());
-
- // Flush all the pending requests.
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
-
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id()));
- EXPECT_EQ(0,
- host_.GetOutstandingRequestsMemoryCost(second_filter->child_id()));
-
- // Sort out all the messages we saw by request.
- ResourceIPCAccumulator::ClassifiedMessages msgs;
- accum_.GetClassifiedMessages(&msgs);
-
- // The 2 requests for the RVH 0 should have been processed.
- ASSERT_EQ(2U, msgs.size());
-
- CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1());
- CheckSuccessfulRequest(msgs[1], net::URLRequestTestJob::test_data_3());
-
- EXPECT_TRUE(host_.blocked_loaders_map_.empty());
-}
-
-// Tests that blocked requests don't leak when the ResourceDispatcherHost goes
-// away. Note that we rely on Purify for finding the leaks if any.
-// If this test turns the Purify bot red, check the ResourceDispatcherHost
-// destructor to make sure the blocked requests are deleted.
-TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) {
- // This second filter is used to emulate a second process.
- scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
- this, browser_context_->GetResourceContext());
-
- host_.BlockRequestsForRoute(filter_->child_id(), 1);
- host_.BlockRequestsForRoute(filter_->child_id(), 2);
- host_.BlockRequestsForRoute(second_filter->child_id(), 1);
-
- MakeTestRequest(filter_.get(), 0, 1, net::URLRequestTestJob::test_url_1());
- MakeTestRequest(filter_.get(), 1, 2, net::URLRequestTestJob::test_url_2());
- MakeTestRequest(filter_.get(), 0, 3, net::URLRequestTestJob::test_url_3());
- MakeTestRequest(second_filter.get(), 1, 4,
- net::URLRequestTestJob::test_url_1());
- MakeTestRequest(filter_.get(), 2, 5, net::URLRequestTestJob::test_url_2());
- MakeTestRequest(filter_.get(), 2, 6, net::URLRequestTestJob::test_url_3());
-
- host_.CancelRequestsForProcess(filter_->child_id());
- host_.CancelRequestsForProcess(second_filter->child_id());
-
- // Flush all the pending requests.
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
-}
-
-// Test the private helper method "CalculateApproximateMemoryCost()".
-TEST_F(ResourceDispatcherHostTest, CalculateApproximateMemoryCost) {
- net::URLRequestContext context;
- net::URLRequest req(GURL("http://www.google.com"), NULL, &context);
- EXPECT_EQ(4427,
- ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req));
-
- // Add 9 bytes of referrer.
- req.set_referrer("123456789");
- EXPECT_EQ(4436,
- ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req));
-
- // Add 33 bytes of upload content.
- std::string upload_content;
- upload_content.resize(33);
- std::fill(upload_content.begin(), upload_content.end(), 'x');
- scoped_refptr<net::UploadData> upload_data(new net::UploadData());
- upload_data->AppendBytes(upload_content.data(), upload_content.size());
- req.set_upload(upload_data);
-
- // Since the upload throttling is disabled, this has no effect on the cost.
- EXPECT_EQ(4436,
- ResourceDispatcherHostImpl::CalculateApproximateMemoryCost(&req));
-}
-
-// Test the private helper method "IncrementOutstandingRequestsMemoryCost()".
-TEST_F(ResourceDispatcherHostTest, IncrementOutstandingRequestsMemoryCost) {
- // Add some counts for render_process_host=7
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(7));
- EXPECT_EQ(1, host_.IncrementOutstandingRequestsMemoryCost(1, 7));
- EXPECT_EQ(2, host_.IncrementOutstandingRequestsMemoryCost(1, 7));
- EXPECT_EQ(3, host_.IncrementOutstandingRequestsMemoryCost(1, 7));
-
- // Add some counts for render_process_host=3
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(3));
- EXPECT_EQ(1, host_.IncrementOutstandingRequestsMemoryCost(1, 3));
- EXPECT_EQ(2, host_.IncrementOutstandingRequestsMemoryCost(1, 3));
-
- // Remove all the counts for render_process_host=7
- EXPECT_EQ(3, host_.GetOutstandingRequestsMemoryCost(7));
- EXPECT_EQ(2, host_.IncrementOutstandingRequestsMemoryCost(-1, 7));
- EXPECT_EQ(1, host_.IncrementOutstandingRequestsMemoryCost(-1, 7));
- EXPECT_EQ(0, host_.IncrementOutstandingRequestsMemoryCost(-1, 7));
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(7));
-
- // Remove all the counts for render_process_host=3
- EXPECT_EQ(2, host_.GetOutstandingRequestsMemoryCost(3));
- EXPECT_EQ(1, host_.IncrementOutstandingRequestsMemoryCost(-1, 3));
- EXPECT_EQ(0, host_.IncrementOutstandingRequestsMemoryCost(-1, 3));
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(3));
-
- // When an entry reaches 0, it should be deleted.
- EXPECT_TRUE(host_.outstanding_requests_memory_cost_map_.end() ==
- host_.outstanding_requests_memory_cost_map_.find(7));
- EXPECT_TRUE(host_.outstanding_requests_memory_cost_map_.end() ==
- host_.outstanding_requests_memory_cost_map_.find(3));
-}
-
-// Test that when too many requests are outstanding for a particular
-// render_process_host_id, any subsequent request from it fails.
-TEST_F(ResourceDispatcherHostTest, TooManyOutstandingRequests) {
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id()));
-
- // Expected cost of each request as measured by
- // ResourceDispatcherHost::CalculateApproximateMemoryCost().
- int kMemoryCostOfTest2Req =
- ResourceDispatcherHostImpl::kAvgBytesPerOutstandingRequest +
- std::string("GET").size() +
- net::URLRequestTestJob::test_url_2().spec().size();
-
- // Tighten the bound on the ResourceDispatcherHost, to speed things up.
- int kMaxCostPerProcess = 440000;
- host_.set_max_outstanding_requests_cost_per_process(kMaxCostPerProcess);
-
- // Determine how many instance of test_url_2() we can request before
- // throttling kicks in.
- size_t kMaxRequests = kMaxCostPerProcess / kMemoryCostOfTest2Req;
-
- // This second filter is used to emulate a second process.
- scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
- this, browser_context_->GetResourceContext());
-
- // Saturate the number of outstanding requests for our process.
- for (size_t i = 0; i < kMaxRequests; ++i) {
- MakeTestRequest(filter_.get(), 0, i + 1,
- net::URLRequestTestJob::test_url_2());
- }
-
- // Issue two more requests for our process -- these should fail immediately.
- MakeTestRequest(filter_.get(), 0, kMaxRequests + 1,
- net::URLRequestTestJob::test_url_2());
- MakeTestRequest(filter_.get(), 0, kMaxRequests + 2,
- net::URLRequestTestJob::test_url_2());
-
- // Issue two requests for the second process -- these should succeed since
- // it is just process 0 that is saturated.
- MakeTestRequest(second_filter.get(), 0, kMaxRequests + 3,
- net::URLRequestTestJob::test_url_2());
- MakeTestRequest(second_filter.get(), 0, kMaxRequests + 4,
- net::URLRequestTestJob::test_url_2());
-
- // Flush all the pending requests.
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
- MessageLoop::current()->RunUntilIdle();
-
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(filter_->child_id()));
-
- // Sorts out all the messages we saw by request.
- ResourceIPCAccumulator::ClassifiedMessages msgs;
- accum_.GetClassifiedMessages(&msgs);
-
- // We issued (kMaxRequests + 4) total requests.
- ASSERT_EQ(kMaxRequests + 4, msgs.size());
-
- // Check that the first kMaxRequests succeeded.
- for (size_t i = 0; i < kMaxRequests; ++i)
- CheckSuccessfulRequest(msgs[i], net::URLRequestTestJob::test_data_2());
-
- // Check that the subsequent two requests (kMaxRequests + 1) and
- // (kMaxRequests + 2) were failed, since the per-process bound was reached.
- for (int i = 0; i < 2; ++i) {
- // Should have sent a single RequestComplete message.
- int index = kMaxRequests + i;
- EXPECT_EQ(1U, msgs[index].size());
- EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[index][0].type());
-
- // The RequestComplete message should have the error code of
- // ERR_INSUFFICIENT_RESOURCES.
- int request_id;
- int error_code;
-
- PickleIterator iter(msgs[index][0]);
- EXPECT_TRUE(IPC::ReadParam(&msgs[index][0], &iter, &request_id));
- EXPECT_TRUE(IPC::ReadParam(&msgs[index][0], &iter, &error_code));
-
- EXPECT_EQ(index + 1, request_id);
- EXPECT_EQ(net::ERR_INSUFFICIENT_RESOURCES, error_code);
- }
-
- // The final 2 requests should have succeeded.
- CheckSuccessfulRequest(msgs[kMaxRequests + 2],
- net::URLRequestTestJob::test_data_2());
- CheckSuccessfulRequest(msgs[kMaxRequests + 3],
- net::URLRequestTestJob::test_data_2());
-}
-
-// Tests that we sniff the mime type for a simple request.
-TEST_F(ResourceDispatcherHostTest, MimeSniffed) {
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-
- std::string raw_headers("HTTP/1.1 200 OK\n\n");
- std::string response_data("<html><title>Test One</title></html>");
- SetResponse(raw_headers, response_data);
-
- HandleScheme("http");
- MakeTestRequest(0, 1, GURL("http:bla"));
-
- // Flush all pending requests.
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
-
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-
- // Sorts out all the messages we saw by request.
- ResourceIPCAccumulator::ClassifiedMessages msgs;
- accum_.GetClassifiedMessages(&msgs);
- ASSERT_EQ(1U, msgs.size());
-
- ResourceResponseHead response_head;
- GetResponseHead(msgs[0], &response_head);
- ASSERT_EQ("text/html", response_head.mime_type);
-}
-
-// Tests that we don't sniff the mime type when the server provides one.
-TEST_F(ResourceDispatcherHostTest, MimeNotSniffed) {
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-
- std::string raw_headers("HTTP/1.1 200 OK\n"
- "Content-type: image/jpeg\n\n");
- std::string response_data("<html><title>Test One</title></html>");
- SetResponse(raw_headers, response_data);
-
- HandleScheme("http");
- MakeTestRequest(0, 1, GURL("http:bla"));
-
- // Flush all pending requests.
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
-
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-
- // Sorts out all the messages we saw by request.
- ResourceIPCAccumulator::ClassifiedMessages msgs;
- accum_.GetClassifiedMessages(&msgs);
- ASSERT_EQ(1U, msgs.size());
-
- ResourceResponseHead response_head;
- GetResponseHead(msgs[0], &response_head);
- ASSERT_EQ("image/jpeg", response_head.mime_type);
-}
-
-// Tests that we don't sniff the mime type when there is no message body.
-TEST_F(ResourceDispatcherHostTest, MimeNotSniffed2) {
-
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-
- SetResponse("HTTP/1.1 304 Not Modified\n\n");
-
- HandleScheme("http");
- MakeTestRequest(0, 1, GURL("http:bla"));
-
- // Flush all pending requests.
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
-
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-
- // Sorts out all the messages we saw by request.
- ResourceIPCAccumulator::ClassifiedMessages msgs;
- accum_.GetClassifiedMessages(&msgs);
- ASSERT_EQ(1U, msgs.size());
-
- ResourceResponseHead response_head;
- GetResponseHead(msgs[0], &response_head);
- ASSERT_EQ("", response_head.mime_type);
-}
-
-TEST_F(ResourceDispatcherHostTest, MimeSniff204) {
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-
- SetResponse("HTTP/1.1 204 No Content\n\n");
-
- HandleScheme("http");
- MakeTestRequest(0, 1, GURL("http:bla"));
-
- // Flush all pending requests.
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
-
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-
- // Sorts out all the messages we saw by request.
- ResourceIPCAccumulator::ClassifiedMessages msgs;
- accum_.GetClassifiedMessages(&msgs);
- ASSERT_EQ(1U, msgs.size());
-
- ResourceResponseHead response_head;
- GetResponseHead(msgs[0], &response_head);
- ASSERT_EQ("text/plain", response_head.mime_type);
-}
-
-TEST_F(ResourceDispatcherHostTest, MimeSniffEmpty) {
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-
- SetResponse("HTTP/1.1 200 OK\n\n");
-
- HandleScheme("http");
- MakeTestRequest(0, 1, GURL("http:bla"));
-
- // Flush all pending requests.
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
-
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-
- // Sorts out all the messages we saw by request.
- ResourceIPCAccumulator::ClassifiedMessages msgs;
- accum_.GetClassifiedMessages(&msgs);
- ASSERT_EQ(1U, msgs.size());
-
- ResourceResponseHead response_head;
- GetResponseHead(msgs[0], &response_head);
- ASSERT_EQ("text/plain", response_head.mime_type);
-}
-
-// Tests for crbug.com/31266 (Non-2xx + application/octet-stream).
-TEST_F(ResourceDispatcherHostTest, ForbiddenDownload) {
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-
- std::string raw_headers("HTTP/1.1 403 Forbidden\n"
- "Content-disposition: attachment; filename=blah\n"
- "Content-type: application/octet-stream\n\n");
- std::string response_data("<html><title>Test One</title></html>");
- SetResponse(raw_headers, response_data);
-
- // Only MAIN_FRAMEs can trigger a download.
- SetResourceType(ResourceType::MAIN_FRAME);
-
- HandleScheme("http");
- MakeTestRequest(0, 1, GURL("http:bla"));
-
- // Flush all pending requests.
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
-
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-
- // Sorts out all the messages we saw by request.
- ResourceIPCAccumulator::ClassifiedMessages msgs;
- accum_.GetClassifiedMessages(&msgs);
-
- // We should have gotten one RequestComplete message.
- ASSERT_EQ(1U, msgs[0].size());
- EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type());
-
- // The RequestComplete message should have had the error code of
- // ERR_FILE_NOT_FOUND.
- int request_id;
- int error_code;
-
- PickleIterator iter(msgs[0][0]);
- EXPECT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &request_id));
- EXPECT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &error_code));
-
- EXPECT_EQ(1, request_id);
- EXPECT_EQ(net::ERR_FILE_NOT_FOUND, error_code);
-}
-
-// Test for http://crbug.com/76202 . We don't want to destroy a
-// download request prematurely when processing a cancellation from
-// the renderer.
-TEST_F(ResourceDispatcherHostTest, IgnoreCancelForDownloads) {
- EXPECT_EQ(0, host_.pending_requests());
-
- int render_view_id = 0;
- int request_id = 1;
-
- std::string raw_headers("HTTP\n"
- "Content-disposition: attachment; filename=foo\n\n");
- std::string response_data("01234567890123456789\x01foobar");
-
- // Get past sniffing metrics in the BufferedResourceHandler. Note that
- // if we don't get past the sniffing metrics, the result will be that
- // the BufferedResourceHandler won't have figured out that it's a download,
- // won't have constructed a DownloadResourceHandler, and and the request
- // will be successfully canceled below, failing the test.
- response_data.resize(1025, ' ');
-
- SetResponse(raw_headers, response_data);
- SetResourceType(ResourceType::MAIN_FRAME);
- SetDelayedCompleteJobGeneration(true);
- HandleScheme("http");
-
- MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah"));
- // Return some data so that the request is identified as a download
- // and the proper resource handlers are created.
- EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
-
- // And now simulate a cancellation coming from the renderer.
- ResourceHostMsg_CancelRequest msg(filter_->child_id(), request_id);
- bool msg_was_ok;
- host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
-
- // Since the request had already started processing as a download,
- // the cancellation above should have been ignored and the request
- // should still be alive.
- EXPECT_EQ(1, host_.pending_requests());
-
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
- EXPECT_EQ(0, host_.GetOutstandingRequestsMemoryCost(0));
-}
-
-TEST_F(ResourceDispatcherHostTest, CancelRequestsForContext) {
- EXPECT_EQ(0, host_.pending_requests());
-
- int render_view_id = 0;
- int request_id = 1;
-
- std::string raw_headers("HTTP\n"
- "Content-disposition: attachment; filename=foo\n\n");
- std::string response_data("01234567890123456789\x01foobar");
- // Get past sniffing metrics.
- response_data.resize(1025, ' ');
-
- SetResponse(raw_headers, response_data);
- SetResourceType(ResourceType::MAIN_FRAME);
- SetDelayedCompleteJobGeneration(true);
- HandleScheme("http");
-
- MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah"));
- // Return some data so that the request is identified as a download
- // and the proper resource handlers are created.
- EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage());
-
- // And now simulate a cancellation coming from the renderer.
- ResourceHostMsg_CancelRequest msg(filter_->child_id(), request_id);
- bool msg_was_ok;
- host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
-
- // Since the request had already started processing as a download,
- // the cancellation above should have been ignored and the request
- // should still be alive.
- EXPECT_EQ(1, host_.pending_requests());
-
- // Cancelling by other methods shouldn't work either.
- host_.CancelRequestsForProcess(render_view_id);
- EXPECT_EQ(1, host_.pending_requests());
-
- // Cancelling by context should work.
- host_.CancelRequestsForContext(filter_->resource_context());
- EXPECT_EQ(0, host_.pending_requests());
-}
-
-// Test the cancelling of requests that are being transferred to a new renderer
-// due to a redirection.
-TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextTransferred) {
- EXPECT_EQ(0, host_.pending_requests());
-
- int render_view_id = 0;
- int request_id = 1;
-
- std::string raw_headers("HTTP/1.1 200 OK\n"
- "Content-Type: text/html; charset=utf-8\n\n");
- std::string response_data("<html>foobar</html>");
-
- SetResponse(raw_headers, response_data);
- SetResourceType(ResourceType::MAIN_FRAME);
- HandleScheme("http");
-
- MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah"));
-
- GlobalRequestID global_request_id(filter_->child_id(), request_id);
- host_.MarkAsTransferredNavigation(global_request_id);
-
- // And now simulate a cancellation coming from the renderer.
- ResourceHostMsg_CancelRequest msg(filter_->child_id(), request_id);
- bool msg_was_ok;
- host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
-
- // Since the request is marked as being transferred,
- // the cancellation above should have been ignored and the request
- // should still be alive.
- EXPECT_EQ(1, host_.pending_requests());
-
- // Cancelling by other methods shouldn't work either.
- host_.CancelRequestsForProcess(render_view_id);
- EXPECT_EQ(1, host_.pending_requests());
-
- // Cancelling by context should work.
- host_.CancelRequestsForContext(filter_->resource_context());
- EXPECT_EQ(0, host_.pending_requests());
-}
-
-TEST_F(ResourceDispatcherHostTest, TransferNavigation) {
- EXPECT_EQ(0, host_.pending_requests());
-
- int render_view_id = 0;
- int request_id = 1;
-
- // Configure initial request.
- SetResponse("HTTP/1.1 302 Found\n"
- "Location: http://other.com/blech\n\n");
-
- SetResourceType(ResourceType::MAIN_FRAME);
- HandleScheme("http");
-
- // Temporarily replace ContentBrowserClient with one that will trigger the
- // transfer navigation code paths.
- ContentBrowserClient* old_client = GetContentClient()->browser();
- TransfersAllNavigationsContentBrowserClient new_client;
- GetContentClient()->set_browser_for_testing(&new_client);
-
- MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah"));
-
- // Restore.
- GetContentClient()->set_browser_for_testing(old_client);
-
- // This second filter is used to emulate a second process.
- scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
- this, browser_context_->GetResourceContext());
-
- int new_render_view_id = 1;
- int new_request_id = 2;
-
- const std::string kResponseBody = "hello world";
- SetResponse("HTTP/1.1 200 OK\n"
- "Content-Type: text/plain\n\n",
- kResponseBody);
-
- ResourceHostMsg_Request request =
- CreateResourceRequest("GET", ResourceType::MAIN_FRAME,
- GURL("http://other.com/blech"));
- request.transferred_request_child_id = filter_->child_id();
- request.transferred_request_request_id = request_id;
-
- ResourceHostMsg_RequestResource transfer_request_msg(
- new_render_view_id, new_request_id, request);
- bool msg_was_ok;
- host_.OnMessageReceived(transfer_request_msg, second_filter, &msg_was_ok);
- MessageLoop::current()->RunUntilIdle();
-
- // Flush all the pending requests.
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
-
- // Check generated messages.
- ResourceIPCAccumulator::ClassifiedMessages msgs;
- accum_.GetClassifiedMessages(&msgs);
-
- ASSERT_EQ(1U, msgs.size());
- CheckSuccessfulRequest(msgs[0], kResponseBody);
-}
-
-TEST_F(ResourceDispatcherHostTest, TransferNavigationAndThenRedirect) {
- EXPECT_EQ(0, host_.pending_requests());
-
- int render_view_id = 0;
- int request_id = 1;
-
- // Configure initial request.
- SetResponse("HTTP/1.1 302 Found\n"
- "Location: http://other.com/blech\n\n");
-
- SetResourceType(ResourceType::MAIN_FRAME);
- HandleScheme("http");
-
- // Temporarily replace ContentBrowserClient with one that will trigger the
- // transfer navigation code paths.
- ContentBrowserClient* old_client = GetContentClient()->browser();
- TransfersAllNavigationsContentBrowserClient new_client;
- GetContentClient()->set_browser_for_testing(&new_client);
-
- MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah"));
-
- // Restore.
- GetContentClient()->set_browser_for_testing(old_client);
-
- // This second filter is used to emulate a second process.
- scoped_refptr<ForwardingFilter> second_filter = new ForwardingFilter(
- this, browser_context_->GetResourceContext());
-
- int new_render_view_id = 1;
- int new_request_id = 2;
-
- // Delay the start of the next request so that we can setup the response for
- // the next URL.
- SetDelayedStartJobGeneration(true);
-
- SetResponse("HTTP/1.1 302 Found\n"
- "Location: http://other.com/blerg\n\n");
-
- ResourceHostMsg_Request request =
- CreateResourceRequest("GET", ResourceType::MAIN_FRAME,
- GURL("http://other.com/blech"));
- request.transferred_request_child_id = filter_->child_id();
- request.transferred_request_request_id = request_id;
-
- ResourceHostMsg_RequestResource transfer_request_msg(
- new_render_view_id, new_request_id, request);
- bool msg_was_ok;
- host_.OnMessageReceived(transfer_request_msg, second_filter, &msg_was_ok);
- MessageLoop::current()->RunUntilIdle();
-
- // Response data for "http://other.com/blerg":
- const std::string kResponseBody = "hello world";
- SetResponse("HTTP/1.1 200 OK\n"
- "Content-Type: text/plain\n\n",
- kResponseBody);
-
- // OK, let the redirect happen.
- SetDelayedStartJobGeneration(false);
- CompleteStartRequest(second_filter, new_request_id);
- MessageLoop::current()->RunUntilIdle();
-
- // Flush all the pending requests.
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
-
- // Now, simulate the renderer choosing to follow the redirect.
- ResourceHostMsg_FollowRedirect redirect_msg(
- new_render_view_id, new_request_id, false, GURL());
- host_.OnMessageReceived(redirect_msg, second_filter, &msg_was_ok);
- MessageLoop::current()->RunUntilIdle();
-
- // Flush all the pending requests.
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
-
- // Check generated messages.
- ResourceIPCAccumulator::ClassifiedMessages msgs;
- accum_.GetClassifiedMessages(&msgs);
-
- ASSERT_EQ(1U, msgs.size());
-
- // We should have received a redirect followed by a "normal" payload.
- EXPECT_EQ(ResourceMsg_ReceivedRedirect::ID, msgs[0][0].type());
- msgs[0].erase(msgs[0].begin());
- CheckSuccessfulRequest(msgs[0], kResponseBody);
-}
-
-TEST_F(ResourceDispatcherHostTest, UnknownURLScheme) {
- EXPECT_EQ(0, host_.pending_requests());
-
- SetResourceType(ResourceType::MAIN_FRAME);
- HandleScheme("http");
-
- MakeTestRequest(0, 1, GURL("foo://bar"));
-
- // Flush all pending requests.
- while (net::URLRequestTestJob::ProcessOnePendingMessage()) {}
-
- // Sort all the messages we saw by request.
- ResourceIPCAccumulator::ClassifiedMessages msgs;
- accum_.GetClassifiedMessages(&msgs);
-
- // We should have gotten one RequestComplete message.
- ASSERT_EQ(1U, msgs[0].size());
- EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][0].type());
-
- // The RequestComplete message should have the error code of
- // ERR_UNKNOWN_URL_SCHEME.
- int request_id;
- int error_code;
-
- PickleIterator iter(msgs[0][0]);
- EXPECT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &request_id));
- EXPECT_TRUE(IPC::ReadParam(&msgs[0][0], &iter, &error_code));
-
- EXPECT_EQ(1, request_id);
- EXPECT_EQ(net::ERR_UNKNOWN_URL_SCHEME, error_code);
-}
-
-TEST_F(ResourceDispatcherHostTest, DataReceivedACKs) {
- EXPECT_EQ(0, host_.pending_requests());
-
- SendDataReceivedACKs(true);
-
- HandleScheme("big-job");
- MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
-
- // Sort all the messages we saw by request.
- ResourceIPCAccumulator::ClassifiedMessages msgs;
- accum_.GetClassifiedMessages(&msgs);
-
- size_t size = msgs[0].size();
-
- EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
- EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
- for (size_t i = 2; i < size - 1; ++i)
- EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
- EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][size - 1].type());
-}
-
-TEST_F(ResourceDispatcherHostTest, DelayedDataReceivedACKs) {
- EXPECT_EQ(0, host_.pending_requests());
-
- HandleScheme("big-job");
- MakeTestRequest(0, 1, GURL("big-job:0123456789,1000000"));
-
- // Sort all the messages we saw by request.
- ResourceIPCAccumulator::ClassifiedMessages msgs;
- accum_.GetClassifiedMessages(&msgs);
-
- // We expect 1x ReceivedResponse, 1x SetDataBuffer, Nx ReceivedData messages.
- EXPECT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type());
- EXPECT_EQ(ResourceMsg_SetDataBuffer::ID, msgs[0][1].type());
- for (size_t i = 2; i < msgs[0].size(); ++i)
- EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
-
- // NOTE: If we fail the above checks then it means that we probably didn't
- // load a big enough response to trigger the delay mechanism we are trying to
- // test!
-
- msgs[0].erase(msgs[0].begin());
- msgs[0].erase(msgs[0].begin());
-
- // ACK all DataReceived messages until we find a RequestComplete message.
- bool complete = false;
- while (!complete) {
- for (size_t i = 0; i < msgs[0].size(); ++i) {
- if (msgs[0][i].type() == ResourceMsg_RequestComplete::ID) {
- complete = true;
- break;
- }
-
- EXPECT_EQ(ResourceMsg_DataReceived::ID, msgs[0][i].type());
-
- ResourceHostMsg_DataReceived_ACK msg(0, 1);
- bool msg_was_ok;
- host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok);
- }
-
- MessageLoop::current()->RunUntilIdle();
-
- msgs.clear();
- accum_.GetClassifiedMessages(&msgs);
- }
-}
-
-} // namespace content
« no previous file with comments | « content/browser/renderer_host/resource_dispatcher_host_impl.cc ('k') | content/browser/renderer_host/resource_handler.h » ('j') | no next file with comments »

Powered by Google App Engine
This is Rietveld 408576698