Updating trunk VERSION from 2139.0 to 2140.0
[chromium-blink-merge.git] / content / child / resource_dispatcher_unittest.cc
blobd878e376b1632d0c3841d83439f35593ee1ca3bb
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.
5 #include <string>
6 #include <vector>
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;
31 namespace content {
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 {
46 public:
47 TestRequestPeer(ResourceLoaderBridge* bridge)
48 : follow_redirects_(true),
49 defer_on_redirect_(false),
50 seen_redirects_(0),
51 cancel_on_receive_response_(false),
52 received_response_(false),
53 total_encoded_data_length_(0),
54 total_downloaded_data_length_(0),
55 complete_(false),
56 bridge_(bridge) {
59 virtual void OnUploadProgress(uint64 position, uint64 size) OVERRIDE {
62 virtual bool OnReceivedRedirect(const net::RedirectInfo& redirect_info,
63 const ResourceResponseInfo& info) OVERRIDE {
64 ++seen_redirects_;
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_)
74 bridge_->Cancel();
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,
83 int data_length,
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(
92 int error_code,
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_);
100 complete_ = true;
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 {
120 return data_;
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_; }
131 private:
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.
137 int seen_redirects_;
139 bool cancel_on_receive_response_;
140 bool received_response_;
142 // Data received. If downloading to file, remains empty.
143 std::string data_;
144 // Total encoded data length, regardless of whether downloading to a file or
145 // not.
146 int total_encoded_data_length_;
147 // Total length when downloading to a file.
148 int total_downloaded_data_length_;
150 bool complete_;
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 {
159 public:
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));
171 delete msg;
172 return true;
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";
182 return -1;
185 ResourceHostMsg_RequestResource::Param params;
186 if (ResourceHostMsg_RequestResource::ID != message_queue_[0].type() ||
187 !ResourceHostMsg_RequestResource::Read(&message_queue_[0], &params)) {
188 ADD_FAILURE() << "Expected ResourceHostMsg_RequestResource message";
189 return -1;
191 ResourceHostMsg_Request request = params.c;
192 EXPECT_EQ(kTestPageUrl, request.url.spec());
193 message_queue_.erase(message_queue_.begin());
194 return params.b;
197 void ConsumeFollowRedirect(int expected_request_id) {
198 ASSERT_FALSE(message_queue_.empty());
199 Tuple1<int> args;
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());
209 Tuple1<int> args;
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());
219 Tuple1<int> args;
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());
229 Tuple1<int> args;
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());
240 Tuple1<int> args;
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;
271 EXPECT_EQ(true,
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(),
293 data.length());
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,
303 encoded_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_; }
326 private:
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
355 // two reads.
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
388 // requests.
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.
440 bridge->Cancel();
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
575 // resumed.
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);
625 bridge->Cancel();
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());
669 bridge.reset();
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.
691 bridge->Cancel();
692 ConsumeCancelRequest(id);
693 ConsumeReleaseDownloadedFile(id);
695 // Deleting the bridge shouldn't send another message to delete the file.
696 bridge.reset();
697 EXPECT_EQ(0u, queued_messages());
700 TEST_F(ResourceDispatcherTest, Cookies) {
701 // FIXME
704 TEST_F(ResourceDispatcherTest, SerializedPostData) {
705 // FIXME
708 class TimeConversionTest : public ResourceDispatcherTest,
709 public RequestPeer {
710 public:
711 virtual bool Send(IPC::Message* msg) OVERRIDE {
712 delete msg;
713 return true;
716 void PerformTest(const ResourceResponseHead& response_head) {
717 scoped_ptr<ResourceLoaderBridge> bridge(CreateBridge());
718 bridge->Start(this);
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 {
730 return true;
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,
741 int data_length,
742 int encoded_data_length) OVERRIDE {
745 virtual void OnCompletedRequest(
746 int error_code,
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_; }
756 private:
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