Chromium Code Reviews| Index: content/browser/loader/resource_dispatcher_host_unittest.cc |
| diff --git a/content/browser/loader/resource_dispatcher_host_unittest.cc b/content/browser/loader/resource_dispatcher_host_unittest.cc |
| index 4a9e27553dd59efdc099870f899e4872016bbef9..4c2b93f4b88f6733f705a60994beaffd71aa3235 100644 |
| --- a/content/browser/loader/resource_dispatcher_host_unittest.cc |
| +++ b/content/browser/loader/resource_dispatcher_host_unittest.cc |
| @@ -15,6 +15,7 @@ |
| #include "content/browser/browser_thread_impl.h" |
| #include "content/browser/child_process_security_policy_impl.h" |
| #include "content/browser/loader/resource_dispatcher_host_impl.h" |
| +#include "content/browser/loader/resource_loader.h" |
| #include "content/browser/loader/resource_message_filter.h" |
| #include "content/browser/loader/resource_request_info_impl.h" |
| #include "content/browser/worker_host/worker_service_impl.h" |
| @@ -523,7 +524,6 @@ class ResourceDispatcherHostTest : public testing::Test, |
| 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()); |
| @@ -594,17 +594,17 @@ class ResourceDispatcherHostTest : public testing::Test, |
| message_loop_.RunUntilIdle(); |
| } |
| - // Creates a request using the current test object as the filter. |
| + // Creates a request using the current test object as the filter and |
| + // SubResource as the resource type. |
| 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); |
| + // Generates a request using the given filter and resource type. |
| + void MakeTestRequestWithResourceType(ResourceMessageFilter* filter, |
| + int render_view_id, int request_id, |
| + const GURL& url, |
| + ResourceType::Type type); |
| void CancelRequest(int request_id); |
| @@ -634,11 +634,6 @@ class ResourceDispatcherHostTest : public testing::Test, |
| 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; |
| } |
| @@ -724,7 +719,6 @@ class ResourceDispatcherHostTest : public testing::Test, |
| std::string response_data_; |
| std::string scheme_; |
| net::URLRequest::ProtocolFactory* old_factory_; |
| - ResourceType::Type resource_type_; |
| bool send_data_received_acks_; |
| std::set<int> child_ids_; |
| static ResourceDispatcherHostTest* test_fixture_; |
| @@ -741,19 +735,21 @@ 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); |
| + MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, |
| + url, ResourceType::SUB_RESOURCE); |
| } |
| -void ResourceDispatcherHostTest::MakeTestRequest( |
| +void ResourceDispatcherHostTest::MakeTestRequestWithResourceType( |
| ResourceMessageFilter* filter, |
| int render_view_id, |
| int request_id, |
| - const GURL& url) { |
| + const GURL& url, |
| + ResourceType::Type type) { |
| // If it's already there, this'll be dropped on the floor, which is fine. |
| child_ids_.insert(filter->child_id()); |
| ResourceHostMsg_Request request = |
| - CreateResourceRequest("GET", resource_type_, url); |
| + CreateResourceRequest("GET", type, url); |
| ResourceHostMsg_RequestResource msg(render_view_id, request_id, request); |
| bool msg_was_ok; |
| host_.OnMessageReceived(msg, filter, &msg_was_ok); |
| @@ -826,6 +822,42 @@ void CheckSuccessfulRequest(const std::vector<IPC::Message>& messages, |
| ASSERT_EQ(ResourceMsg_RequestComplete::ID, messages[3].type()); |
| } |
| +void CheckSuccessfulRedirect(const std::vector<IPC::Message>& messages, |
| + const std::string& reference_data) { |
|
mmenke
2013/10/24 20:27:21
nit: Fix indentation
jkarlin2
2013/10/25 14:10:21
Done.
|
| + ASSERT_EQ(5U, messages.size()); |
| + ASSERT_EQ(ResourceMsg_ReceivedRedirect::ID, messages[0].type()); |
| + |
| + const std::vector<IPC::Message> second_req_msgs = |
| + std::vector<IPC::Message>(messages.begin() + 1, messages.end()); |
| + CheckSuccessfulRequest(second_req_msgs, reference_data); |
| +} |
| + |
| +void CheckSuccessfulDetachableRequest( |
|
mmenke
2013/10/24 20:27:21
Maybe DetachedRequest instead?
jkarlin2
2013/10/25 14:10:21
Done.
|
| + const std::vector<IPC::Message>& messages) { |
| + // A successful request will have received 2 messages: |
| + // ReceivedResponse (indicates headers received) |
| + // RequestComplete (request is done) |
| + // |
| + // This function verifies that we received 2 messages and that they |
| + // are appropriate. |
| + ASSERT_EQ(2U, messages.size()); |
| + |
| + // The first messages should be received response |
| + ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, messages[0].type()); |
| + |
| + // The last message should be all data received. |
| + ASSERT_EQ(ResourceMsg_RequestComplete::ID, messages[1].type()); |
| + |
| + // Verify that there was no error. |
| + int request_id; |
| + int error_code; |
| + |
| + PickleIterator iter(messages[1]); |
| + EXPECT_TRUE(IPC::ReadParam(&messages[1], &iter, &request_id)); |
| + EXPECT_TRUE(IPC::ReadParam(&messages[1], &iter, &error_code)); |
| + EXPECT_EQ(0, error_code); |
| +} |
| + |
| void CheckFailedRequest(const std::vector<IPC::Message>& messages, |
| const std::string& reference_data, |
| int expected_error) { |
| @@ -852,6 +884,14 @@ TEST_F(ResourceDispatcherHostTest, TestMany) { |
| MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); |
| MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2()); |
| MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3()); |
| + MakeTestRequest(0, 4, net::URLRequestTestJob::test_url_4()); |
| + MakeTestRequest(0, 5, net::URLRequestTestJob::test_url_redirect_to_url_2()); |
| + |
| + // Finish the redirection |
| + ResourceHostMsg_FollowRedirect redirect_msg(5, false, GURL()); |
| + bool msg_was_ok; |
| + host_.OnMessageReceived(redirect_msg, filter_.get(), &msg_was_ok); |
| + base::MessageLoop::current()->RunUntilIdle(); |
| // flush all the pending requests |
| while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} |
| @@ -860,12 +900,14 @@ TEST_F(ResourceDispatcherHostTest, TestMany) { |
| ResourceIPCAccumulator::ClassifiedMessages msgs; |
| accum_.GetClassifiedMessages(&msgs); |
| - // there are three requests, so we should have gotten them classified as such |
| - ASSERT_EQ(3U, msgs.size()); |
| + // there are five requests, so we should have gotten them classified as such |
| + ASSERT_EQ(5U, 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()); |
| + CheckSuccessfulRequest(msgs[3], net::URLRequestTestJob::test_data_4()); |
| + CheckSuccessfulRedirect(msgs[4], net::URLRequestTestJob::test_data_2()); |
| } |
| void CheckCancelledRequestCompleteMessage(const IPC::Message& message) { |
| @@ -881,13 +923,20 @@ void CheckCancelledRequestCompleteMessage(const IPC::Message& message) { |
| 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. |
| +// Tests whether messages get canceled properly. We issue four requests, |
| +// cancel two of them, and make sure that each sent the proper notifications. |
| TEST_F(ResourceDispatcherHostTest, Cancel) { |
| MakeTestRequest(0, 1, net::URLRequestTestJob::test_url_1()); |
| MakeTestRequest(0, 2, net::URLRequestTestJob::test_url_2()); |
| MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3()); |
| + MakeTestRequestWithResourceType(filter_.get(), 0, 4, |
| + net::URLRequestTestJob::test_url_4(), |
| + ResourceType::PREFETCH); // detachable type |
| + |
| CancelRequest(2); |
| + // Cancel request must come from the renderer for a detachable resource to |
| + // delay. |
| + host_.CancelRequest(filter_->child_id(), 4, true); |
| // flush all the pending requests |
| while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} |
| @@ -896,11 +945,13 @@ TEST_F(ResourceDispatcherHostTest, Cancel) { |
| ResourceIPCAccumulator::ClassifiedMessages msgs; |
| accum_.GetClassifiedMessages(&msgs); |
| - // there are three requests, so we should have gotten them classified as such |
| - ASSERT_EQ(3U, msgs.size()); |
| + // there are four requests, so we should have gotten them classified as such |
| + ASSERT_EQ(4U, msgs.size()); |
| CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); |
| CheckSuccessfulRequest(msgs[2], net::URLRequestTestJob::test_data_3()); |
| + // The detachable resource should have delayed its cancellation and completed. |
| + CheckSuccessfulDetachableRequest(msgs[3]); |
| // Check that request 2 got canceled. |
| ASSERT_EQ(2U, msgs[1].size()); |
| @@ -908,6 +959,124 @@ TEST_F(ResourceDispatcherHostTest, Cancel) { |
| CheckCancelledRequestCompleteMessage(msgs[1][1]); |
| } |
| +// Shows that detachable requests will timeout if the request takes too long to |
| +// complete. |
| +TEST_F(ResourceDispatcherHostTest, DetachableResourceTimesOut) { |
| + MakeTestRequestWithResourceType(filter_.get(), 0, 1, |
| + net::URLRequestTestJob::test_url_2(), |
| + ResourceType::PREFETCH); // detachable type |
| + ResourceLoader* loader = host_.GetLoader(filter_->child_id(), 1); |
| + EXPECT_TRUE(loader); |
| + loader->set_detachable_delay_ms(200); |
| + base::MessageLoop::current()->RunUntilIdle(); |
| + host_.CancelRequest(filter_->child_id(), 1, true); |
|
mmenke
2013/10/24 20:27:21
Question: Should we consider timing out all prefe
jkarlin2
2013/10/25 14:10:21
That's an important issue that we need to address,
mmenke
2013/10/25 14:57:51
I completely agree that it doesn't belong in this
|
| + |
| + EXPECT_EQ(1, host_.pending_requests()); |
| + |
| + // Wait until after the delay timer times out before we start processing any |
| + // messages. |
| + base::OneShotTimer<base::MessageLoop> timer; |
| + timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(210), |
| + base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle); |
| + base::MessageLoop::current()->Run(); |
| + |
| + // We should have cancelled the prefetch by now. |
| + EXPECT_EQ(0, host_.pending_requests()); |
| + |
| + // In case any messages are still to be processed. |
| + while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} |
| + base::MessageLoop::current()->RunUntilIdle(); |
| + |
| + ResourceIPCAccumulator::ClassifiedMessages msgs; |
| + accum_.GetClassifiedMessages(&msgs); |
| + |
| + ASSERT_EQ(1U, msgs.size()); |
| + |
| + // The request should have cancelled. |
| + ASSERT_EQ(2U, msgs[0].size()); |
| + ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type()); |
| + CheckCancelledRequestCompleteMessage(msgs[0][1]); |
| +} |
| + |
| +// If the filter has disappeared (original process dies) then detachable |
| +// resources should continue to load. |
| +TEST_F(ResourceDispatcherHostTest, DeletedFilterDetachable) { |
| + ResourceHostMsg_Request request = CreateResourceRequest( |
| + "GET", ResourceType::PREFETCH, net::URLRequestTestJob::test_url_4()); |
| + |
| + ResourceHostMsg_RequestResource msg(0, 1, request); |
| + bool msg_was_ok; |
| + host_.OnMessageReceived(msg, filter_, &msg_was_ok); |
| + |
| + // Remove the filter before processing the request. |
| + GlobalRequestID global_request_id(filter_->child_id(), 1); |
| + ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest( |
| + host_.GetURLRequest(global_request_id)); |
| + info->filter_.reset(); |
| + |
| + EXPECT_EQ(1, host_.pending_requests()); |
| + |
| + KickOffRequest(); |
| + |
| + // Make sure the request wasn't canceled early. |
| + EXPECT_EQ(1, host_.pending_requests()); |
| + |
| + while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} |
| + base::MessageLoop::current()->RunUntilIdle(); |
| + |
| + EXPECT_EQ(0, host_.pending_requests()); |
| + |
| + // Because the filter was gone, no messages should have been sent. |
| + // TODO(jkarlin): It would be nice to verify that we successfully completed |
| + // the request, but we have no messages to verify with. |
| + ResourceIPCAccumulator::ClassifiedMessages msgs; |
| + accum_.GetClassifiedMessages(&msgs); |
| + ASSERT_EQ(0U, msgs.size()); |
| +} |
| + |
| +// If the filter has disappeared (original process dies) then detachable |
| +// resources should continue to load, even when redirected. |
| +TEST_F(ResourceDispatcherHostTest, DeletedFilterDetachableRedirect) { |
| + ResourceHostMsg_Request request = CreateResourceRequest( |
| + "GET", ResourceType::PREFETCH, |
| + net::URLRequestTestJob::test_url_redirect_to_url_2()); |
| + |
| + ResourceHostMsg_RequestResource msg(0, 1, request); |
| + bool msg_was_ok; |
| + host_.OnMessageReceived(msg, filter_, &msg_was_ok); |
| + |
| + // Remove the filter before processing the request. |
| + GlobalRequestID global_request_id(filter_->child_id(), 1); |
| + ResourceRequestInfoImpl* info = ResourceRequestInfoImpl::ForRequest( |
| + host_.GetURLRequest(global_request_id)); |
| + info->filter_.reset(); |
| + |
| + EXPECT_EQ(1, host_.pending_requests()); |
| + // Verify no redirects before resetting the filter. |
| + net::URLRequest* url_request = host_.GetURLRequest(global_request_id); |
| + EXPECT_EQ(1u, url_request->url_chain().size()); |
| + KickOffRequest(); |
| + |
| + // Verify that a redirect was followed. |
| + EXPECT_EQ(2u, url_request->url_chain().size()); |
| + |
| + // Make sure the request wasn't canceled early. |
| + EXPECT_EQ(1, host_.pending_requests()); |
| + |
| + // Finish up the request. |
| + while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} |
| + base::MessageLoop::current()->RunUntilIdle(); |
| + |
| + EXPECT_EQ(0, host_.pending_requests()); |
| + |
| + // Because the filter was deleted, no messages should have been sent. |
| + // TODO(jkarlin): It would be nice to verify that we successfully completed |
| + // the request, but we have no messages to verify with. |
| + ResourceIPCAccumulator::ClassifiedMessages msgs; |
| + accum_.GetClassifiedMessages(&msgs); |
| + ASSERT_EQ(0U, msgs.size()); |
| +} |
| + |
| TEST_F(ResourceDispatcherHostTest, CancelWhileStartIsDeferred) { |
| bool was_deleted = false; |
| @@ -1077,15 +1246,23 @@ TEST_F(ResourceDispatcherHostTest, TestProcessCancel) { |
| ResourceHostMsg_Request request = CreateResourceRequest( |
| "GET", ResourceType::SUB_RESOURCE, net::URLRequestTestJob::test_url_1()); |
| - MakeTestRequest(test_filter.get(), 0, 1, |
| - net::URLRequestTestJob::test_url_1()); |
| + MakeTestRequestWithResourceType(test_filter.get(), 0, 1, |
| + net::URLRequestTestJob::test_url_1(), |
| + ResourceType::SUB_RESOURCE); |
| // 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()); |
| + MakeTestRequestWithResourceType(test_filter.get(), 0, 3, |
| + net::URLRequestTestJob::test_url_3(), |
| + ResourceType::SUB_RESOURCE); |
| + |
| + // request 4 goes to us |
| + MakeTestRequestWithResourceType(filter_.get(), 0, 4, |
| + net::URLRequestTestJob::test_url_4(), |
| + ResourceType::PREFETCH); // detachable type |
| + |
| // Make sure all requests have finished stage one. test_url_1 will have |
| // finished. |
| @@ -1097,7 +1274,9 @@ TEST_F(ResourceDispatcherHostTest, TestProcessCancel) { |
| // breaks the whole test. |
| //EXPECT_EQ(3, host_.pending_requests()); |
| - // Process each request for one level so one callback is called. |
| + // Process test_url_2 and test_url_3 for one level so one callback is called. |
| + // We'll cancel test_url_4 (detachable) before processing it to verify that it |
| + // delays the cancel. |
| for (int i = 0; i < 2; i++) |
| EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage()); |
| @@ -1113,11 +1292,52 @@ TEST_F(ResourceDispatcherHostTest, TestProcessCancel) { |
| // 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. |
| + // We should have gotten two results. |
| ResourceIPCAccumulator::ClassifiedMessages msgs; |
| accum_.GetClassifiedMessages(&msgs); |
| - ASSERT_EQ(1U, msgs.size()); |
| + ASSERT_EQ(2U, msgs.size()); |
| CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_2()); |
| + // We cancelled the detachable request before it finished, and it should have |
| + // delayed and completed regardless. |
| + CheckSuccessfulDetachableRequest(msgs[1]); |
| +} |
| + |
| +TEST_F(ResourceDispatcherHostTest, TestProcessCancelDetachableTimesOut) { |
|
mmenke
2013/10/24 20:27:21
None of these tests exercises the cancel+timeout i
jkarlin2
2013/10/25 14:10:21
CancelRequestsForProcess calls CancelRequestsForRo
mmenke
2013/10/25 14:57:51
Ah, I'm fine with that then.
mmenke
2013/10/25 15:17:55
"Fine with that" meaning "Fine with it as it is"
|
| + MakeTestRequestWithResourceType(filter_.get(), 0, 1, |
| + net::URLRequestTestJob::test_url_4(), |
| + ResourceType::PREFETCH); // detachable type |
| + ResourceLoader* loader = host_.GetLoader(filter_->child_id(), 1); |
| + EXPECT_TRUE(loader); |
| + loader->set_detachable_delay_ms(200); |
| + base::MessageLoop::current()->RunUntilIdle(); |
| + |
| + // Cancel the requests to the test process. |
| + host_.CancelRequestsForProcess(filter_->child_id()); |
| + EXPECT_EQ(1, host_.pending_requests()); |
| + |
| + // Wait until after the delay timer times out before we start processing any |
| + // messages. |
| + base::OneShotTimer<base::MessageLoop> timer; |
| + timer.Start(FROM_HERE, base::TimeDelta::FromMilliseconds(210), |
| + base::MessageLoop::current(), &base::MessageLoop::QuitWhenIdle); |
| + base::MessageLoop::current()->Run(); |
| + |
| + // We should have cancelled the prefetch by now. |
| + EXPECT_EQ(0, host_.pending_requests()); |
| + |
| + // In case any messages are still to be processed. |
| + while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} |
| + base::MessageLoop::current()->RunUntilIdle(); |
| + |
| + ResourceIPCAccumulator::ClassifiedMessages msgs; |
| + accum_.GetClassifiedMessages(&msgs); |
| + |
| + ASSERT_EQ(1U, msgs.size()); |
| + |
| + // The request should have cancelled. |
| + ASSERT_EQ(2U, msgs[0].size()); |
| + ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type()); |
| + CheckCancelledRequestCompleteMessage(msgs[0][1]); |
| } |
| // Tests blocking and resuming requests. |
| @@ -1186,6 +1406,10 @@ TEST_F(ResourceDispatcherHostTest, TestBlockingCancelingRequests) { |
| MakeTestRequest(1, 2, net::URLRequestTestJob::test_url_2()); |
| MakeTestRequest(0, 3, net::URLRequestTestJob::test_url_3()); |
| MakeTestRequest(1, 4, net::URLRequestTestJob::test_url_1()); |
| + // Blocked detachable resources should not delay cancellation. |
| + MakeTestRequestWithResourceType(filter_.get(), 1, 5, |
| + net::URLRequestTestJob::test_url_4(), |
| + ResourceType::PREFETCH); // detachable type |
| // Flush all the pending requests. |
| while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} |
| @@ -1218,12 +1442,21 @@ TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) { |
| 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()); |
| + MakeTestRequestWithResourceType(filter_.get(), 0, 1, |
| + net::URLRequestTestJob::test_url_1(), |
| + ResourceType::SUB_RESOURCE); |
| + MakeTestRequestWithResourceType(second_filter.get(), 0, 2, |
| + net::URLRequestTestJob::test_url_2(), |
| + ResourceType::SUB_RESOURCE); |
| + MakeTestRequestWithResourceType(filter_.get(), 0, 3, |
| + net::URLRequestTestJob::test_url_3(), |
| + ResourceType::SUB_RESOURCE); |
| + MakeTestRequestWithResourceType(second_filter.get(), 0, 4, |
| + net::URLRequestTestJob::test_url_1(), |
| + ResourceType::SUB_RESOURCE); |
| + MakeTestRequestWithResourceType(second_filter.get(), 0, 5, |
| + net::URLRequestTestJob::test_url_4(), |
| + ResourceType::PREFETCH); // detachable type |
| // Simulate process death. |
| host_.CancelRequestsForProcess(second_filter->child_id()); |
| @@ -1235,7 +1468,8 @@ TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsProcessDies) { |
| ResourceIPCAccumulator::ClassifiedMessages msgs; |
| accum_.GetClassifiedMessages(&msgs); |
| - // The 2 requests for the RVH 0 should have been processed. |
| + // The 2 requests for the RVH 0 should have been processed. Note that |
| + // blocked detachable requests are canceled without delay. |
| ASSERT_EQ(2U, msgs.size()); |
| CheckSuccessfulRequest(msgs[0], net::URLRequestTestJob::test_data_1()); |
| @@ -1257,13 +1491,30 @@ TEST_F(ResourceDispatcherHostTest, TestBlockedRequestsDontLeak) { |
| 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()); |
| + MakeTestRequestWithResourceType(filter_.get(), 0, 1, |
| + net::URLRequestTestJob::test_url_1(), |
| + ResourceType::SUB_RESOURCE); |
| + MakeTestRequestWithResourceType(filter_.get(), 1, 2, |
| + net::URLRequestTestJob::test_url_2(), |
| + ResourceType::SUB_RESOURCE); |
| + MakeTestRequestWithResourceType(filter_.get(), 0, 3, |
| + net::URLRequestTestJob::test_url_3(), |
| + ResourceType::SUB_RESOURCE); |
| + MakeTestRequestWithResourceType(second_filter.get(), 1, 4, |
| + net::URLRequestTestJob::test_url_1(), |
| + ResourceType::SUB_RESOURCE); |
| + MakeTestRequestWithResourceType(filter_.get(), 2, 5, |
| + net::URLRequestTestJob::test_url_2(), |
| + ResourceType::SUB_RESOURCE); |
| + MakeTestRequestWithResourceType(filter_.get(), 2, 6, |
| + net::URLRequestTestJob::test_url_3(), |
| + ResourceType::SUB_RESOURCE); |
| + MakeTestRequestWithResourceType(filter_.get(), 0, 7, |
| + net::URLRequestTestJob::test_url_4(), |
| + ResourceType::PREFETCH); // detachable type |
| + MakeTestRequestWithResourceType(second_filter.get(), 1, 8, |
| + net::URLRequestTestJob::test_url_4(), |
| + ResourceType::PREFETCH); // detachable type |
| host_.CancelRequestsForProcess(filter_->child_id()); |
| host_.CancelRequestsForProcess(second_filter->child_id()); |
| @@ -1322,22 +1573,27 @@ TEST_F(ResourceDispatcherHostTest, TooMuchOutstandingRequestsMemory) { |
| // 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()); |
| + MakeTestRequestWithResourceType(filter_.get(), 0, i + 1, |
| + net::URLRequestTestJob::test_url_2(), |
| + ResourceType::SUB_RESOURCE); |
| } |
| // 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()); |
| + MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequests + 1, |
| + net::URLRequestTestJob::test_url_2(), |
| + ResourceType::SUB_RESOURCE); |
| + MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequests + 2, |
| + net::URLRequestTestJob::test_url_2(), |
| + ResourceType::SUB_RESOURCE); |
| // 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()); |
| + MakeTestRequestWithResourceType(second_filter.get(), 0, kMaxRequests + 3, |
| + net::URLRequestTestJob::test_url_2(), |
| + ResourceType::SUB_RESOURCE); |
| + MakeTestRequestWithResourceType(second_filter.get(), 0, kMaxRequests + 4, |
| + net::URLRequestTestJob::test_url_2(), |
| + ResourceType::SUB_RESOURCE); |
| // Flush all the pending requests. |
| while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} |
| @@ -1388,23 +1644,27 @@ TEST_F(ResourceDispatcherHostTest, TooManyOutstandingRequests) { |
| // Saturate the number of outstanding requests for our process. |
| for (size_t i = 0; i < kMaxRequestsPerProcess; ++i) { |
| - MakeTestRequest(filter_.get(), 0, i + 1, |
| - net::URLRequestTestJob::test_url_2()); |
| + MakeTestRequestWithResourceType(filter_.get(), 0, i + 1, |
| + net::URLRequestTestJob::test_url_2(), |
| + ResourceType::SUB_RESOURCE); |
| } |
| // Issue another request for our process -- this should fail immediately. |
| - MakeTestRequest(filter_.get(), 0, kMaxRequestsPerProcess + 1, |
| - net::URLRequestTestJob::test_url_2()); |
| + MakeTestRequestWithResourceType(filter_.get(), 0, kMaxRequestsPerProcess + 1, |
| + net::URLRequestTestJob::test_url_2(), |
| + ResourceType::SUB_RESOURCE); |
| // Issue a request for the second process -- this should succeed, because it |
| // is just process 0 that is saturated. |
| - MakeTestRequest(second_filter.get(), 0, kMaxRequestsPerProcess + 2, |
| - net::URLRequestTestJob::test_url_2()); |
| + MakeTestRequestWithResourceType( |
| + second_filter.get(), 0, kMaxRequestsPerProcess + 2, |
| + net::URLRequestTestJob::test_url_2(), ResourceType::SUB_RESOURCE); |
| // Issue a request for the third process -- this should fail, because the |
| // global limit has been reached. |
| - MakeTestRequest(third_filter.get(), 0, kMaxRequestsPerProcess + 3, |
| - net::URLRequestTestJob::test_url_2()); |
| + MakeTestRequestWithResourceType( |
| + third_filter.get(), 0, kMaxRequestsPerProcess + 3, |
| + net::URLRequestTestJob::test_url_2(), ResourceType::SUB_RESOURCE); |
| // Flush all the pending requests. |
| while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} |
| @@ -1544,11 +1804,11 @@ TEST_F(ResourceDispatcherHostTest, ForbiddenDownload) { |
| 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")); |
| + |
| + // Only MAIN_FRAMEs can trigger a download. |
| + MakeTestRequestWithResourceType(filter_.get(), 0, 1, GURL("http:bla"), |
| + ResourceType::MAIN_FRAME); |
| // Flush all pending requests. |
| while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} |
| @@ -1595,11 +1855,12 @@ TEST_F(ResourceDispatcherHostTest, IgnoreCancelForDownloads) { |
| 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")); |
| + MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, |
| + GURL("http://example.com/blah"), |
| + ResourceType::MAIN_FRAME); |
| // Return some data so that the request is identified as a download |
| // and the proper resource handlers are created. |
| EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage()); |
| @@ -1630,11 +1891,12 @@ TEST_F(ResourceDispatcherHostTest, CancelRequestsForContext) { |
| 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")); |
| + MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, |
| + GURL("http://example.com/blah"), |
| + ResourceType::MAIN_FRAME); |
| // Return some data so that the request is identified as a download |
| // and the proper resource handlers are created. |
| EXPECT_TRUE(net::URLRequestTestJob::ProcessOnePendingMessage()); |
| @@ -1658,6 +1920,35 @@ TEST_F(ResourceDispatcherHostTest, CancelRequestsForContext) { |
| EXPECT_EQ(0, host_.pending_requests()); |
| } |
| +TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextDetachable) { |
| + EXPECT_EQ(0, host_.pending_requests()); |
| + |
| + int render_view_id = 0; |
| + int request_id = 1; |
| + |
| + MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, |
| + net::URLRequestTestJob::test_url_4(), |
| + ResourceType::PREFETCH); // detachable type |
| + |
| + // Simulate a cancellation coming from the renderer. |
| + ResourceHostMsg_CancelRequest msg(request_id); |
| + bool msg_was_ok; |
| + host_.OnMessageReceived(msg, filter_.get(), &msg_was_ok); |
|
mmenke
2013/10/24 20:27:21
Should the other tests cancel this way, rather tha
jkarlin2
2013/10/25 14:10:21
Done.
|
| + |
| + // Since the request had already started processing as detachable, |
| + // the cancellation above should have been ignored and the request |
| + // should still be alive. |
| + EXPECT_EQ(1, host_.pending_requests()); |
| + |
| + // Cancelling by other methods should also be delayed. |
| + 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) { |
| @@ -1671,10 +1962,12 @@ TEST_F(ResourceDispatcherHostTest, CancelRequestsForContextTransferred) { |
| 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")); |
| + MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, |
| + GURL("http://example.com/blah"), |
| + ResourceType::MAIN_FRAME); |
| + |
| GlobalRequestID global_request_id(filter_->child_id(), request_id); |
| host_.MarkAsTransferredNavigation(global_request_id, |
| @@ -1711,7 +2004,6 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationHtml) { |
| 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 |
| @@ -1719,7 +2011,8 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationHtml) { |
| TransfersAllNavigationsContentBrowserClient new_client; |
| ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client); |
| - MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah")); |
| + MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, |
| + GURL("http://example.com/blah"), ResourceType::MAIN_FRAME); |
| // Now that we're blocked on the redirect, update the response and unblock by |
| // telling the AsyncResourceHandler to follow the redirect. |
| @@ -1782,7 +2075,6 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationText) { |
| 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 |
| @@ -1790,7 +2082,9 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationText) { |
| TransfersAllNavigationsContentBrowserClient new_client; |
| ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client); |
| - MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah")); |
| + MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, |
| + GURL("http://example.com/blah"), |
| + ResourceType::MAIN_FRAME); |
| // Now that we're blocked on the redirect, update the response and unblock by |
| // telling the AsyncResourceHandler to follow the redirect. Use a text/plain |
| @@ -1854,7 +2148,6 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationWithProcessCrash) { |
| "Location: http://other.com/blech\n\n"); |
| const std::string kResponseBody = "hello world"; |
| - SetResourceType(ResourceType::MAIN_FRAME); |
| HandleScheme("http"); |
| // Temporarily replace ContentBrowserClient with one that will trigger the |
| @@ -1943,7 +2236,6 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationWithTwoRedirects) { |
| 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 |
| @@ -1951,7 +2243,9 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationWithTwoRedirects) { |
| TransfersAllNavigationsContentBrowserClient new_client; |
| ContentBrowserClient* old_client = SetBrowserClientForTesting(&new_client); |
| - MakeTestRequest(render_view_id, request_id, GURL("http://example.com/blah")); |
| + MakeTestRequestWithResourceType(filter_.get(), render_view_id, request_id, |
| + GURL("http://example.com/blah"), |
| + ResourceType::MAIN_FRAME); |
| // Now that we're blocked on the redirect, simulate hitting another redirect. |
| SetResponse("HTTP/1.1 302 Found\n" |
| @@ -2024,10 +2318,10 @@ TEST_F(ResourceDispatcherHostTest, TransferNavigationWithTwoRedirects) { |
| TEST_F(ResourceDispatcherHostTest, UnknownURLScheme) { |
| EXPECT_EQ(0, host_.pending_requests()); |
| - SetResourceType(ResourceType::MAIN_FRAME); |
| HandleScheme("http"); |
| - MakeTestRequest(0, 1, GURL("foo://bar")); |
| + MakeTestRequestWithResourceType(filter_.get(), 0, 1, GURL("foo://bar"), |
| + ResourceType::MAIN_FRAME); |
| // Flush all pending requests. |
| while (net::URLRequestTestJob::ProcessOnePendingMessage()) {} |
| @@ -2074,6 +2368,29 @@ TEST_F(ResourceDispatcherHostTest, DataReceivedACKs) { |
| EXPECT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][size - 1].type()); |
| } |
| +// Request a very large detachable resource. This verifies that the data is not |
| +// sent to the render process. |
| +TEST_F(ResourceDispatcherHostTest, DetachableNoDataSentOrReceived) { |
| + EXPECT_EQ(0, host_.pending_requests()); |
| + |
| + SendDataReceivedACKs(true); |
| + |
| + HandleScheme("big-job"); |
| + |
| + // This request would normally result in many messages (>300). |
| + MakeTestRequestWithResourceType(filter_.get(), 0, 1, |
| + GURL("big-job:0123456789,1000000"), |
| + ResourceType::PREFETCH); // detachable type |
| + |
| + // Sort all the messages we saw by request. |
| + ResourceIPCAccumulator::ClassifiedMessages msgs; |
| + accum_.GetClassifiedMessages(&msgs); |
| + |
| + EXPECT_EQ(2u, msgs[0].size()); |
| + ASSERT_EQ(ResourceMsg_ReceivedResponse::ID, msgs[0][0].type()); |
| + ASSERT_EQ(ResourceMsg_RequestComplete::ID, msgs[0][1].type()); |
| +} |
| + |
| TEST_F(ResourceDispatcherHostTest, DelayedDataReceivedACKs) { |
| EXPECT_EQ(0, host_.pending_requests()); |