1 // Copyright (c) 2012 The Chromium Authors. All rights reserved.
2 // Use of this source code is governed by a BSD-style license that can be
3 // found in the LICENSE file.
8 #include "base/macros.h"
9 #include "base/memory/scoped_ptr.h"
10 #include "base/memory/shared_memory.h"
11 #include "base/message_loop/message_loop.h"
12 #include "base/process/process.h"
13 #include "base/process/process_handle.h"
14 #include "base/run_loop.h"
15 #include "base/stl_util.h"
16 #include "content/child/request_extra_data.h"
17 #include "content/child/request_info.h"
18 #include "content/child/resource_dispatcher.h"
19 #include "content/common/appcache_interfaces.h"
20 #include "content/common/resource_messages.h"
21 #include "content/common/service_worker/service_worker_types.h"
22 #include "content/public/child/request_peer.h"
23 #include "content/public/common/resource_response.h"
24 #include "net/base/net_errors.h"
25 #include "net/http/http_response_headers.h"
26 #include "testing/gtest/include/gtest/gtest.h"
27 #include "webkit/child/resource_loader_bridge.h"
29 using webkit_glue::ResourceLoaderBridge
;
33 static const char kTestPageUrl
[] = "http://www.google.com/";
34 static const char kTestPageHeaders
[] =
35 "HTTP/1.1 200 OK\nContent-Type:text/html\n\n";
36 static const char kTestPageMimeType
[] = "text/html";
37 static const char kTestPageCharset
[] = "";
38 static const char kTestPageContents
[] =
39 "<html><head><title>Google</title></head><body><h1>Google</h1></body></html>";
40 static const char kTestRedirectHeaders
[] =
41 "HTTP/1.1 302 Found\nLocation:http://www.google.com/\n\n";
43 // Listens for request response data and stores it so that it can be compared
44 // to the reference data.
45 class TestRequestPeer
: public RequestPeer
{
47 TestRequestPeer(ResourceLoaderBridge
* bridge
)
48 : follow_redirects_(true),
49 defer_on_redirect_(false),
51 cancel_on_receive_response_(false),
52 received_response_(false),
53 total_encoded_data_length_(0),
54 total_downloaded_data_length_(0),
59 virtual void OnUploadProgress(uint64 position
, uint64 size
) OVERRIDE
{
62 virtual bool OnReceivedRedirect(const net::RedirectInfo
& redirect_info
,
63 const ResourceResponseInfo
& info
) OVERRIDE
{
65 if (defer_on_redirect_
)
66 bridge_
->SetDefersLoading(true);
67 return follow_redirects_
;
70 virtual void OnReceivedResponse(const ResourceResponseInfo
& info
) OVERRIDE
{
71 EXPECT_FALSE(received_response_
);
72 received_response_
= true;
73 if (cancel_on_receive_response_
)
77 virtual void OnDownloadedData(int len
, int encoded_data_length
) OVERRIDE
{
78 total_downloaded_data_length_
+= len
;
79 total_encoded_data_length_
+= encoded_data_length
;
82 virtual void OnReceivedData(const char* data
,
84 int encoded_data_length
) OVERRIDE
{
85 EXPECT_TRUE(received_response_
);
86 EXPECT_FALSE(complete_
);
87 data_
.append(data
, data_length
);
88 total_encoded_data_length_
+= encoded_data_length
;
91 virtual void OnCompletedRequest(
93 bool was_ignored_by_handler
,
94 bool stale_copy_in_cache
,
95 const std::string
& security_info
,
96 const base::TimeTicks
& completion_time
,
97 int64 total_transfer_size
) OVERRIDE
{
98 EXPECT_TRUE(received_response_
);
99 EXPECT_FALSE(complete_
);
103 void set_follow_redirects(bool follow_redirects
) {
104 follow_redirects_
= follow_redirects
;
107 void set_defer_on_redirect(bool defer_on_redirect
) {
108 defer_on_redirect_
= defer_on_redirect
;
111 void set_cancel_on_receive_response(bool cancel_on_receive_response
) {
112 cancel_on_receive_response_
= cancel_on_receive_response
;
115 int seen_redirects() const { return seen_redirects_
; }
117 bool received_response() const { return received_response_
; }
119 const std::string
& data() const {
122 int total_encoded_data_length() const {
123 return total_encoded_data_length_
;
125 int total_downloaded_data_length() const {
126 return total_downloaded_data_length_
;
129 bool complete() const { return complete_
; }
132 // True if should follow redirects, false if should cancel them.
133 bool follow_redirects_
;
134 // True if the request should be deferred on redirects.
135 bool defer_on_redirect_
;
136 // Number of total redirects seen.
139 bool cancel_on_receive_response_
;
140 bool received_response_
;
142 // Data received. If downloading to file, remains empty.
144 // Total encoded data length, regardless of whether downloading to a file or
146 int total_encoded_data_length_
;
147 // Total length when downloading to a file.
148 int total_downloaded_data_length_
;
152 ResourceLoaderBridge
* bridge_
;
154 DISALLOW_COPY_AND_ASSIGN(TestRequestPeer
);
157 // Sets up the message sender override for the unit test.
158 class ResourceDispatcherTest
: public testing::Test
, public IPC::Sender
{
160 ResourceDispatcherTest() : dispatcher_(this) {}
162 virtual ~ResourceDispatcherTest() {
163 STLDeleteContainerPairSecondPointers(shared_memory_map_
.begin(),
164 shared_memory_map_
.end());
167 // Emulates IPC send operations (IPC::Sender) by adding
168 // pending messages to the queue.
169 virtual bool Send(IPC::Message
* msg
) OVERRIDE
{
170 message_queue_
.push_back(IPC::Message(*msg
));
175 size_t queued_messages() const { return message_queue_
.size(); }
177 // Returns the ID of the consumed request. Can't make assumptions about the
178 // ID, because numbering is based on a global.
179 int ConsumeRequestResource() {
180 if (message_queue_
.empty()) {
181 ADD_FAILURE() << "Missing resource request message";
185 ResourceHostMsg_RequestResource::Param params
;
186 if (ResourceHostMsg_RequestResource::ID
!= message_queue_
[0].type() ||
187 !ResourceHostMsg_RequestResource::Read(&message_queue_
[0], ¶ms
)) {
188 ADD_FAILURE() << "Expected ResourceHostMsg_RequestResource message";
191 ResourceHostMsg_Request request
= params
.c
;
192 EXPECT_EQ(kTestPageUrl
, request
.url
.spec());
193 message_queue_
.erase(message_queue_
.begin());
197 void ConsumeFollowRedirect(int expected_request_id
) {
198 ASSERT_FALSE(message_queue_
.empty());
200 ASSERT_EQ(ResourceHostMsg_FollowRedirect::ID
, message_queue_
[0].type());
201 ASSERT_TRUE(ResourceHostMsg_FollowRedirect::Read(
202 &message_queue_
[0], &args
));
203 EXPECT_EQ(expected_request_id
, args
.a
);
204 message_queue_
.erase(message_queue_
.begin());
207 void ConsumeDataReceived_ACK(int expected_request_id
) {
208 ASSERT_FALSE(message_queue_
.empty());
210 ASSERT_EQ(ResourceHostMsg_DataReceived_ACK::ID
, message_queue_
[0].type());
211 ASSERT_TRUE(ResourceHostMsg_DataReceived_ACK::Read(
212 &message_queue_
[0], &args
));
213 EXPECT_EQ(expected_request_id
, args
.a
);
214 message_queue_
.erase(message_queue_
.begin());
217 void ConsumeDataDownloaded_ACK(int expected_request_id
) {
218 ASSERT_FALSE(message_queue_
.empty());
220 ASSERT_EQ(ResourceHostMsg_DataDownloaded_ACK::ID
, message_queue_
[0].type());
221 ASSERT_TRUE(ResourceHostMsg_DataDownloaded_ACK::Read(
222 &message_queue_
[0], &args
));
223 EXPECT_EQ(expected_request_id
, args
.a
);
224 message_queue_
.erase(message_queue_
.begin());
227 void ConsumeReleaseDownloadedFile(int expected_request_id
) {
228 ASSERT_FALSE(message_queue_
.empty());
230 ASSERT_EQ(ResourceHostMsg_ReleaseDownloadedFile::ID
,
231 message_queue_
[0].type());
232 ASSERT_TRUE(ResourceHostMsg_ReleaseDownloadedFile::Read(
233 &message_queue_
[0], &args
));
234 EXPECT_EQ(expected_request_id
, args
.a
);
235 message_queue_
.erase(message_queue_
.begin());
238 void ConsumeCancelRequest(int expected_request_id
) {
239 ASSERT_FALSE(message_queue_
.empty());
241 ASSERT_EQ(ResourceHostMsg_CancelRequest::ID
, message_queue_
[0].type());
242 ASSERT_TRUE(ResourceHostMsg_CancelRequest::Read(
243 &message_queue_
[0], &args
));
244 EXPECT_EQ(expected_request_id
, args
.a
);
245 message_queue_
.erase(message_queue_
.begin());
248 void NotifyReceivedRedirect(int request_id
) {
249 ResourceResponseHead head
;
250 std::string
raw_headers(kTestRedirectHeaders
);
251 std::replace(raw_headers
.begin(), raw_headers
.end(), '\n', '\0');
252 head
.headers
= new net::HttpResponseHeaders(raw_headers
);
253 head
.error_code
= net::OK
;
254 net::RedirectInfo redirect_info
;
255 redirect_info
.status_code
= 302;
256 redirect_info
.new_method
= "GET";
257 redirect_info
.new_url
= GURL(kTestPageUrl
);
258 redirect_info
.new_first_party_for_cookies
= GURL(kTestPageUrl
);
259 EXPECT_EQ(true, dispatcher_
.OnMessageReceived(
260 ResourceMsg_ReceivedRedirect(request_id
, redirect_info
, head
)));
263 void NotifyReceivedResponse(int request_id
) {
264 ResourceResponseHead head
;
265 std::string
raw_headers(kTestPageHeaders
);
266 std::replace(raw_headers
.begin(), raw_headers
.end(), '\n', '\0');
267 head
.headers
= new net::HttpResponseHeaders(raw_headers
);
268 head
.mime_type
= kTestPageMimeType
;
269 head
.charset
= kTestPageCharset
;
270 head
.error_code
= net::OK
;
272 dispatcher_
.OnMessageReceived(
273 ResourceMsg_ReceivedResponse(request_id
, head
)));
276 void NotifySetDataBuffer(int request_id
, size_t buffer_size
) {
277 base::SharedMemory
* shared_memory
= new base::SharedMemory();
278 ASSERT_FALSE(shared_memory_map_
[request_id
]);
279 shared_memory_map_
[request_id
] = shared_memory
;
280 EXPECT_TRUE(shared_memory
->CreateAndMapAnonymous(buffer_size
));
282 base::SharedMemoryHandle duplicate_handle
;
283 EXPECT_TRUE(shared_memory
->ShareToProcess(
284 base::Process::Current().handle(), &duplicate_handle
));
285 EXPECT_TRUE(dispatcher_
.OnMessageReceived(
286 ResourceMsg_SetDataBuffer(request_id
, duplicate_handle
,
287 shared_memory
->requested_size(), 0)));
290 void NotifyDataReceived(int request_id
, std::string data
) {
291 ASSERT_LE(data
.length(), shared_memory_map_
[request_id
]->requested_size());
292 memcpy(shared_memory_map_
[request_id
]->memory(), data
.c_str(),
295 EXPECT_TRUE(dispatcher_
.OnMessageReceived(
296 ResourceMsg_DataReceived(request_id
, 0, data
.length(), data
.length())));
299 void NotifyDataDownloaded(int request_id
, int decoded_length
,
300 int encoded_length
) {
301 EXPECT_TRUE(dispatcher_
.OnMessageReceived(
302 ResourceMsg_DataDownloaded(request_id
, decoded_length
,
306 void NotifyRequestComplete(int request_id
, size_t total_size
) {
307 ResourceMsg_RequestCompleteData request_complete_data
;
308 request_complete_data
.error_code
= net::OK
;
309 request_complete_data
.was_ignored_by_handler
= false;
310 request_complete_data
.exists_in_cache
= false;
311 request_complete_data
.encoded_data_length
= total_size
;
312 EXPECT_TRUE(dispatcher_
.OnMessageReceived(
313 ResourceMsg_RequestComplete(request_id
, request_complete_data
)));
316 ResourceLoaderBridge
* CreateBridge() {
317 return CreateBridgeInternal(false);
320 ResourceLoaderBridge
* CreateBridgeForDownloadToFile() {
321 return CreateBridgeInternal(true);
324 ResourceDispatcher
* dispatcher() { return &dispatcher_
; }
327 ResourceLoaderBridge
* CreateBridgeInternal(bool download_to_file
) {
328 RequestInfo request_info
;
329 request_info
.method
= "GET";
330 request_info
.url
= GURL(kTestPageUrl
);
331 request_info
.first_party_for_cookies
= GURL(kTestPageUrl
);
332 request_info
.referrer
= GURL();
333 request_info
.headers
= std::string();
334 request_info
.load_flags
= 0;
335 request_info
.requestor_pid
= 0;
336 request_info
.request_type
= RESOURCE_TYPE_SUB_RESOURCE
;
337 request_info
.appcache_host_id
= kAppCacheNoHostId
;
338 request_info
.routing_id
= 0;
339 request_info
.download_to_file
= download_to_file
;
340 RequestExtraData extra_data
;
341 request_info
.extra_data
= &extra_data
;
343 return dispatcher_
.CreateBridge(request_info
);
346 // Map of request IDs to shared memory.
347 std::map
<int, base::SharedMemory
*> shared_memory_map_
;
349 std::vector
<IPC::Message
> message_queue_
;
350 ResourceDispatcher dispatcher_
;
351 base::MessageLoop message_loop_
;
354 // Does a simple request and tests that the correct data is received. Simulates
356 TEST_F(ResourceDispatcherTest
, RoundTrip
) {
357 // Number of bytes received in the first read.
358 const size_t kFirstReceiveSize
= 2;
359 ASSERT_LT(kFirstReceiveSize
, strlen(kTestPageContents
));
361 scoped_ptr
<ResourceLoaderBridge
> bridge(CreateBridge());
362 TestRequestPeer
peer(bridge
.get());
364 EXPECT_TRUE(bridge
->Start(&peer
));
365 int id
= ConsumeRequestResource();
366 EXPECT_EQ(0u, queued_messages());
368 NotifyReceivedResponse(id
);
369 EXPECT_EQ(0u, queued_messages());
370 EXPECT_TRUE(peer
.received_response());
372 NotifySetDataBuffer(id
, strlen(kTestPageContents
));
373 NotifyDataReceived(id
, std::string(kTestPageContents
, kFirstReceiveSize
));
374 ConsumeDataReceived_ACK(id
);
375 EXPECT_EQ(0u, queued_messages());
377 NotifyDataReceived(id
, kTestPageContents
+ kFirstReceiveSize
);
378 ConsumeDataReceived_ACK(id
);
379 EXPECT_EQ(0u, queued_messages());
381 NotifyRequestComplete(id
, strlen(kTestPageContents
));
382 EXPECT_EQ(kTestPageContents
, peer
.data());
383 EXPECT_TRUE(peer
.complete());
384 EXPECT_EQ(0u, queued_messages());
387 // Tests that the request IDs are straight when there are two interleaving
389 TEST_F(ResourceDispatcherTest
, MultipleRequests
) {
390 const char kTestPageContents2
[] = "Not kTestPageContents";
392 scoped_ptr
<ResourceLoaderBridge
> bridge1(CreateBridge());
393 TestRequestPeer
peer1(bridge1
.get());
394 scoped_ptr
<ResourceLoaderBridge
> bridge2(CreateBridge());
395 TestRequestPeer
peer2(bridge2
.get());
397 EXPECT_TRUE(bridge1
->Start(&peer1
));
398 int id1
= ConsumeRequestResource();
399 EXPECT_TRUE(bridge2
->Start(&peer2
));
400 int id2
= ConsumeRequestResource();
401 EXPECT_EQ(0u, queued_messages());
403 NotifyReceivedResponse(id1
);
404 EXPECT_TRUE(peer1
.received_response());
405 EXPECT_FALSE(peer2
.received_response());
406 NotifyReceivedResponse(id2
);
407 EXPECT_TRUE(peer2
.received_response());
408 EXPECT_EQ(0u, queued_messages());
410 NotifySetDataBuffer(id2
, strlen(kTestPageContents2
));
411 NotifyDataReceived(id2
, kTestPageContents2
);
412 ConsumeDataReceived_ACK(id2
);
413 NotifySetDataBuffer(id1
, strlen(kTestPageContents
));
414 NotifyDataReceived(id1
, kTestPageContents
);
415 ConsumeDataReceived_ACK(id1
);
416 EXPECT_EQ(0u, queued_messages());
418 NotifyRequestComplete(id1
, strlen(kTestPageContents
));
419 EXPECT_EQ(kTestPageContents
, peer1
.data());
420 EXPECT_TRUE(peer1
.complete());
421 EXPECT_FALSE(peer2
.complete());
423 NotifyRequestComplete(id2
, strlen(kTestPageContents2
));
424 EXPECT_EQ(kTestPageContents2
, peer2
.data());
425 EXPECT_TRUE(peer2
.complete());
427 EXPECT_EQ(0u, queued_messages());
430 // Tests that the cancel method prevents other messages from being received.
431 TEST_F(ResourceDispatcherTest
, Cancel
) {
432 scoped_ptr
<ResourceLoaderBridge
> bridge(CreateBridge());
433 TestRequestPeer
peer(bridge
.get());
435 EXPECT_TRUE(bridge
->Start(&peer
));
436 int id
= ConsumeRequestResource();
437 EXPECT_EQ(0u, queued_messages());
439 // Cancel the request.
441 ConsumeCancelRequest(id
);
443 // Any future messages related to the request should be ignored.
444 NotifyReceivedResponse(id
);
445 NotifySetDataBuffer(id
, strlen(kTestPageContents
));
446 NotifyDataReceived(id
, kTestPageContents
);
447 NotifyRequestComplete(id
, strlen(kTestPageContents
));
449 EXPECT_EQ(0u, queued_messages());
450 EXPECT_EQ("", peer
.data());
451 EXPECT_FALSE(peer
.received_response());
452 EXPECT_FALSE(peer
.complete());
455 // Tests that calling cancel during a callback works as expected.
456 TEST_F(ResourceDispatcherTest
, CancelDuringCallback
) {
457 scoped_ptr
<ResourceLoaderBridge
> bridge(CreateBridge());
458 TestRequestPeer
peer(bridge
.get());
459 peer
.set_cancel_on_receive_response(true);
461 EXPECT_TRUE(bridge
->Start(&peer
));
462 int id
= ConsumeRequestResource();
463 EXPECT_EQ(0u, queued_messages());
465 NotifyReceivedResponse(id
);
466 EXPECT_TRUE(peer
.received_response());
467 // Request should have been cancelled.
468 ConsumeCancelRequest(id
);
470 // Any future messages related to the request should be ignored.
471 NotifySetDataBuffer(id
, strlen(kTestPageContents
));
472 NotifyDataReceived(id
, kTestPageContents
);
473 NotifyRequestComplete(id
, strlen(kTestPageContents
));
475 EXPECT_EQ(0u, queued_messages());
476 EXPECT_EQ("", peer
.data());
477 EXPECT_FALSE(peer
.complete());
480 // Checks that redirects work as expected.
481 TEST_F(ResourceDispatcherTest
, Redirect
) {
482 scoped_ptr
<ResourceLoaderBridge
> bridge(CreateBridge());
483 TestRequestPeer
peer(bridge
.get());
485 EXPECT_TRUE(bridge
->Start(&peer
));
486 int id
= ConsumeRequestResource();
488 NotifyReceivedRedirect(id
);
489 ConsumeFollowRedirect(id
);
490 EXPECT_EQ(1, peer
.seen_redirects());
492 NotifyReceivedRedirect(id
);
493 ConsumeFollowRedirect(id
);
494 EXPECT_EQ(2, peer
.seen_redirects());
496 NotifyReceivedResponse(id
);
497 EXPECT_TRUE(peer
.received_response());
499 NotifySetDataBuffer(id
, strlen(kTestPageContents
));
500 NotifyDataReceived(id
, kTestPageContents
);
501 ConsumeDataReceived_ACK(id
);
503 NotifyRequestComplete(id
, strlen(kTestPageContents
));
504 EXPECT_EQ(kTestPageContents
, peer
.data());
505 EXPECT_TRUE(peer
.complete());
506 EXPECT_EQ(0u, queued_messages());
507 EXPECT_EQ(2, peer
.seen_redirects());
510 // Tests that that cancelling during a redirect method prevents other messages
511 // from being received.
512 TEST_F(ResourceDispatcherTest
, CancelDuringRedirect
) {
513 scoped_ptr
<ResourceLoaderBridge
> bridge(CreateBridge());
514 TestRequestPeer
peer(bridge
.get());
515 peer
.set_follow_redirects(false);
517 EXPECT_TRUE(bridge
->Start(&peer
));
518 int id
= ConsumeRequestResource();
519 EXPECT_EQ(0u, queued_messages());
521 // Redirect the request, which triggers a cancellation.
522 NotifyReceivedRedirect(id
);
523 ConsumeCancelRequest(id
);
524 EXPECT_EQ(1, peer
.seen_redirects());
525 EXPECT_EQ(0u, queued_messages());
527 // Any future messages related to the request should be ignored. In practice,
528 // only the NotifyRequestComplete should be received after this point.
529 NotifyReceivedRedirect(id
);
530 NotifyReceivedResponse(id
);
531 NotifySetDataBuffer(id
, strlen(kTestPageContents
));
532 NotifyDataReceived(id
, kTestPageContents
);
533 NotifyRequestComplete(id
, strlen(kTestPageContents
));
535 EXPECT_EQ(0u, queued_messages());
536 EXPECT_EQ("", peer
.data());
537 EXPECT_FALSE(peer
.complete());
538 EXPECT_EQ(1, peer
.seen_redirects());
541 // Checks that deferring a request delays messages until it's resumed.
542 TEST_F(ResourceDispatcherTest
, Defer
) {
543 scoped_ptr
<ResourceLoaderBridge
> bridge(CreateBridge());
544 TestRequestPeer
peer(bridge
.get());
546 EXPECT_TRUE(bridge
->Start(&peer
));
547 int id
= ConsumeRequestResource();
548 EXPECT_EQ(0u, queued_messages());
550 bridge
->SetDefersLoading(true);
551 NotifyReceivedResponse(id
);
552 NotifySetDataBuffer(id
, strlen(kTestPageContents
));
553 NotifyDataReceived(id
, kTestPageContents
);
554 NotifyRequestComplete(id
, strlen(kTestPageContents
));
556 // None of the messages should have been processed yet, so no queued messages
557 // to the browser process, and no data received by the peer.
558 EXPECT_EQ(0u, queued_messages());
559 EXPECT_EQ("", peer
.data());
560 EXPECT_FALSE(peer
.complete());
561 EXPECT_EQ(0, peer
.seen_redirects());
563 // Resuming the request should asynchronously unleash the deferred messages.
564 bridge
->SetDefersLoading(false);
565 base::RunLoop().RunUntilIdle();
567 ConsumeDataReceived_ACK(id
);
568 EXPECT_EQ(0u, queued_messages());
569 EXPECT_TRUE(peer
.received_response());
570 EXPECT_EQ(kTestPageContents
, peer
.data());
571 EXPECT_TRUE(peer
.complete());
574 // Checks that deferring a request during a redirect delays messages until it's
576 TEST_F(ResourceDispatcherTest
, DeferOnRedirect
) {
577 scoped_ptr
<ResourceLoaderBridge
> bridge(CreateBridge());
578 TestRequestPeer
peer(bridge
.get());
579 peer
.set_defer_on_redirect(true);
581 EXPECT_TRUE(bridge
->Start(&peer
));
582 int id
= ConsumeRequestResource();
583 EXPECT_EQ(0u, queued_messages());
585 // The request should be deferred during the redirect, including the message
586 // to follow the redirect.
587 NotifyReceivedRedirect(id
);
588 NotifyReceivedResponse(id
);
589 NotifySetDataBuffer(id
, strlen(kTestPageContents
));
590 NotifyDataReceived(id
, kTestPageContents
);
591 NotifyRequestComplete(id
, strlen(kTestPageContents
));
593 // None of the messages should have been processed yet, so no queued messages
594 // to the browser process, and no data received by the peer.
595 EXPECT_EQ(0u, queued_messages());
596 EXPECT_EQ("", peer
.data());
597 EXPECT_FALSE(peer
.complete());
598 EXPECT_EQ(1, peer
.seen_redirects());
600 // Resuming the request should asynchronously unleash the deferred messages.
601 bridge
->SetDefersLoading(false);
602 base::RunLoop().RunUntilIdle();
604 ConsumeFollowRedirect(id
);
605 ConsumeDataReceived_ACK(id
);
607 EXPECT_EQ(0u, queued_messages());
608 EXPECT_TRUE(peer
.received_response());
609 EXPECT_EQ(kTestPageContents
, peer
.data());
610 EXPECT_TRUE(peer
.complete());
611 EXPECT_EQ(1, peer
.seen_redirects());
614 // Checks that a deferred request that's cancelled doesn't receive any messages.
615 TEST_F(ResourceDispatcherTest
, CancelDeferredRequest
) {
616 scoped_ptr
<ResourceLoaderBridge
> bridge(CreateBridge());
617 TestRequestPeer
peer(bridge
.get());
619 EXPECT_TRUE(bridge
->Start(&peer
));
620 int id
= ConsumeRequestResource();
621 EXPECT_EQ(0u, queued_messages());
623 bridge
->SetDefersLoading(true);
624 NotifyReceivedRedirect(id
);
626 ConsumeCancelRequest(id
);
628 NotifyRequestComplete(id
, 0);
629 base::RunLoop().RunUntilIdle();
631 // None of the messages should have been processed.
632 EXPECT_EQ(0u, queued_messages());
633 EXPECT_EQ("", peer
.data());
634 EXPECT_FALSE(peer
.complete());
635 EXPECT_EQ(0, peer
.seen_redirects());
638 TEST_F(ResourceDispatcherTest
, DownloadToFile
) {
639 scoped_ptr
<ResourceLoaderBridge
> bridge(CreateBridgeForDownloadToFile());
640 TestRequestPeer
peer(bridge
.get());
641 const int kDownloadedIncrement
= 100;
642 const int kEncodedIncrement
= 50;
644 EXPECT_TRUE(bridge
->Start(&peer
));
645 int id
= ConsumeRequestResource();
646 EXPECT_EQ(0u, queued_messages());
648 NotifyReceivedResponse(id
);
649 EXPECT_EQ(0u, queued_messages());
650 EXPECT_TRUE(peer
.received_response());
652 int expected_total_downloaded_length
= 0;
653 int expected_total_encoded_length
= 0;
654 for (int i
= 0; i
< 10; ++i
) {
655 NotifyDataDownloaded(id
, kDownloadedIncrement
, kEncodedIncrement
);
656 ConsumeDataDownloaded_ACK(id
);
657 expected_total_downloaded_length
+= kDownloadedIncrement
;
658 expected_total_encoded_length
+= kEncodedIncrement
;
659 EXPECT_EQ(expected_total_downloaded_length
,
660 peer
.total_downloaded_data_length());
661 EXPECT_EQ(expected_total_encoded_length
, peer
.total_encoded_data_length());
664 NotifyRequestComplete(id
, strlen(kTestPageContents
));
665 EXPECT_EQ("", peer
.data());
666 EXPECT_TRUE(peer
.complete());
667 EXPECT_EQ(0u, queued_messages());
670 ConsumeReleaseDownloadedFile(id
);
671 EXPECT_EQ(0u, queued_messages());
672 EXPECT_EQ(expected_total_downloaded_length
,
673 peer
.total_downloaded_data_length());
674 EXPECT_EQ(expected_total_encoded_length
, peer
.total_encoded_data_length());
677 // Make sure that when a download to file is cancelled, the file is destroyed.
678 TEST_F(ResourceDispatcherTest
, CancelDownloadToFile
) {
679 scoped_ptr
<ResourceLoaderBridge
> bridge(CreateBridgeForDownloadToFile());
680 TestRequestPeer
peer(bridge
.get());
682 EXPECT_TRUE(bridge
->Start(&peer
));
683 int id
= ConsumeRequestResource();
684 EXPECT_EQ(0u, queued_messages());
686 NotifyReceivedResponse(id
);
687 EXPECT_EQ(0u, queued_messages());
688 EXPECT_TRUE(peer
.received_response());
690 // Cancelling the request deletes the file.
692 ConsumeCancelRequest(id
);
693 ConsumeReleaseDownloadedFile(id
);
695 // Deleting the bridge shouldn't send another message to delete the file.
697 EXPECT_EQ(0u, queued_messages());
700 TEST_F(ResourceDispatcherTest
, Cookies
) {
704 TEST_F(ResourceDispatcherTest
, SerializedPostData
) {
708 class TimeConversionTest
: public ResourceDispatcherTest
,
711 virtual bool Send(IPC::Message
* msg
) OVERRIDE
{
716 void PerformTest(const ResourceResponseHead
& response_head
) {
717 scoped_ptr
<ResourceLoaderBridge
> bridge(CreateBridge());
720 dispatcher()->OnMessageReceived(
721 ResourceMsg_ReceivedResponse(0, response_head
));
724 // RequestPeer methods.
725 virtual void OnUploadProgress(uint64 position
, uint64 size
) OVERRIDE
{
728 virtual bool OnReceivedRedirect(const net::RedirectInfo
& redirect_info
,
729 const ResourceResponseInfo
& info
) OVERRIDE
{
733 virtual void OnReceivedResponse(const ResourceResponseInfo
& info
) OVERRIDE
{
734 response_info_
= info
;
737 virtual void OnDownloadedData(int len
, int encoded_data_length
) OVERRIDE
{
740 virtual void OnReceivedData(const char* data
,
742 int encoded_data_length
) OVERRIDE
{
745 virtual void OnCompletedRequest(
747 bool was_ignored_by_handler
,
748 bool stale_copy_in_cache
,
749 const std::string
& security_info
,
750 const base::TimeTicks
& completion_time
,
751 int64 total_transfer_size
) OVERRIDE
{
754 const ResourceResponseInfo
& response_info() const { return response_info_
; }
757 ResourceResponseInfo response_info_
;
760 // TODO(simonjam): Enable this when 10829031 lands.
761 TEST_F(TimeConversionTest
, DISABLED_ProperlyInitialized
) {
762 ResourceResponseHead response_head
;
763 response_head
.error_code
= net::OK
;
764 response_head
.request_start
= base::TimeTicks::FromInternalValue(5);
765 response_head
.response_start
= base::TimeTicks::FromInternalValue(15);
766 response_head
.load_timing
.request_start_time
= base::Time::Now();
767 response_head
.load_timing
.request_start
=
768 base::TimeTicks::FromInternalValue(10);
769 response_head
.load_timing
.connect_timing
.connect_start
=
770 base::TimeTicks::FromInternalValue(13);
772 PerformTest(response_head
);
774 EXPECT_LT(base::TimeTicks(), response_info().load_timing
.request_start
);
775 EXPECT_EQ(base::TimeTicks(),
776 response_info().load_timing
.connect_timing
.dns_start
);
777 EXPECT_LE(response_head
.load_timing
.request_start
,
778 response_info().load_timing
.connect_timing
.connect_start
);
781 TEST_F(TimeConversionTest
, PartiallyInitialized
) {
782 ResourceResponseHead response_head
;
783 response_head
.error_code
= net::OK
;
784 response_head
.request_start
= base::TimeTicks::FromInternalValue(5);
785 response_head
.response_start
= base::TimeTicks::FromInternalValue(15);
787 PerformTest(response_head
);
789 EXPECT_EQ(base::TimeTicks(), response_info().load_timing
.request_start
);
790 EXPECT_EQ(base::TimeTicks(),
791 response_info().load_timing
.connect_timing
.dns_start
);
794 TEST_F(TimeConversionTest
, NotInitialized
) {
795 ResourceResponseHead response_head
;
796 response_head
.error_code
= net::OK
;
798 PerformTest(response_head
);
800 EXPECT_EQ(base::TimeTicks(), response_info().load_timing
.request_start
);
801 EXPECT_EQ(base::TimeTicks(),
802 response_info().load_timing
.connect_timing
.dns_start
);
805 } // namespace content