Fix crash on app list start page contents not existing.
[chromium-blink-merge.git] / content / child / resource_dispatcher_unittest.cc
blobe0938d1aad6c14cef3b412bd54adf016fbf8dd20
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_handle.h"
13 #include "base/run_loop.h"
14 #include "base/stl_util.h"
15 #include "content/child/request_extra_data.h"
16 #include "content/child/request_info.h"
17 #include "content/child/resource_dispatcher.h"
18 #include "content/common/appcache_interfaces.h"
19 #include "content/common/resource_messages.h"
20 #include "content/common/service_worker/service_worker_types.h"
21 #include "content/public/child/request_peer.h"
22 #include "content/public/common/resource_response.h"
23 #include "net/base/net_errors.h"
24 #include "net/http/http_response_headers.h"
25 #include "testing/gtest/include/gtest/gtest.h"
27 namespace content {
29 static const char kTestPageUrl[] = "http://www.google.com/";
30 static const char kTestPageHeaders[] =
31 "HTTP/1.1 200 OK\nContent-Type:text/html\n\n";
32 static const char kTestPageMimeType[] = "text/html";
33 static const char kTestPageCharset[] = "";
34 static const char kTestPageContents[] =
35 "<html><head><title>Google</title></head><body><h1>Google</h1></body></html>";
36 static const char kTestRedirectHeaders[] =
37 "HTTP/1.1 302 Found\nLocation:http://www.google.com/\n\n";
39 // Listens for request response data and stores it so that it can be compared
40 // to the reference data.
41 class TestRequestPeer : public RequestPeer {
42 public:
43 TestRequestPeer(ResourceDispatcher* dispatcher)
44 : follow_redirects_(true),
45 defer_on_redirect_(false),
46 seen_redirects_(0),
47 cancel_on_receive_response_(false),
48 received_response_(false),
49 total_encoded_data_length_(0),
50 total_downloaded_data_length_(0),
51 complete_(false),
52 dispatcher_(dispatcher),
53 request_id_(0) {
56 void set_request_id(int request_id) { request_id_ = request_id; }
58 void OnUploadProgress(uint64 position, uint64 size) override {}
60 bool OnReceivedRedirect(const net::RedirectInfo& redirect_info,
61 const ResourceResponseInfo& info) override {
62 ++seen_redirects_;
63 if (defer_on_redirect_)
64 dispatcher_->SetDefersLoading(request_id_, true);
65 return follow_redirects_;
68 void OnReceivedResponse(const ResourceResponseInfo& info) override {
69 EXPECT_FALSE(received_response_);
70 received_response_ = true;
71 if (cancel_on_receive_response_)
72 dispatcher_->Cancel(request_id_);
75 void OnDownloadedData(int len, int encoded_data_length) override {
76 total_downloaded_data_length_ += len;
77 total_encoded_data_length_ += encoded_data_length;
80 void OnReceivedData(const char* data,
81 int data_length,
82 int encoded_data_length) override {
83 EXPECT_TRUE(received_response_);
84 EXPECT_FALSE(complete_);
85 data_.append(data, data_length);
86 total_encoded_data_length_ += encoded_data_length;
89 void OnCompletedRequest(int error_code,
90 bool was_ignored_by_handler,
91 bool stale_copy_in_cache,
92 const std::string& security_info,
93 const base::TimeTicks& completion_time,
94 int64 total_transfer_size) override {
95 EXPECT_TRUE(received_response_);
96 EXPECT_FALSE(complete_);
97 complete_ = true;
100 void set_follow_redirects(bool follow_redirects) {
101 follow_redirects_ = follow_redirects;
104 void set_defer_on_redirect(bool defer_on_redirect) {
105 defer_on_redirect_ = defer_on_redirect;
108 void set_cancel_on_receive_response(bool cancel_on_receive_response) {
109 cancel_on_receive_response_ = cancel_on_receive_response;
112 int seen_redirects() const { return seen_redirects_; }
114 bool received_response() const { return received_response_; }
116 const std::string& data() const {
117 return data_;
119 int total_encoded_data_length() const {
120 return total_encoded_data_length_;
122 int total_downloaded_data_length() const {
123 return total_downloaded_data_length_;
126 bool complete() const { return complete_; }
128 private:
129 // True if should follow redirects, false if should cancel them.
130 bool follow_redirects_;
131 // True if the request should be deferred on redirects.
132 bool defer_on_redirect_;
133 // Number of total redirects seen.
134 int seen_redirects_;
136 bool cancel_on_receive_response_;
137 bool received_response_;
139 // Data received. If downloading to file, remains empty.
140 std::string data_;
141 // Total encoded data length, regardless of whether downloading to a file or
142 // not.
143 int total_encoded_data_length_;
144 // Total length when downloading to a file.
145 int total_downloaded_data_length_;
147 bool complete_;
149 ResourceDispatcher* dispatcher_;
150 int request_id_;
152 DISALLOW_COPY_AND_ASSIGN(TestRequestPeer);
155 // Sets up the message sender override for the unit test.
156 class ResourceDispatcherTest : public testing::Test, public IPC::Sender {
157 public:
158 ResourceDispatcherTest() : dispatcher_(this, message_loop_.task_runner()) {}
160 ~ResourceDispatcherTest() override {
161 STLDeleteContainerPairSecondPointers(shared_memory_map_.begin(),
162 shared_memory_map_.end());
165 // Emulates IPC send operations (IPC::Sender) by adding
166 // pending messages to the queue.
167 bool Send(IPC::Message* msg) override {
168 message_queue_.push_back(IPC::Message(*msg));
169 delete msg;
170 return true;
173 size_t queued_messages() const { return message_queue_.size(); }
175 // Returns the ID of the consumed request. Can't make assumptions about the
176 // ID, because numbering is based on a global.
177 int ConsumeRequestResource() {
178 if (message_queue_.empty()) {
179 ADD_FAILURE() << "Missing resource request message";
180 return -1;
183 ResourceHostMsg_RequestResource::Param params;
184 if (ResourceHostMsg_RequestResource::ID != message_queue_[0].type() ||
185 !ResourceHostMsg_RequestResource::Read(&message_queue_[0], &params)) {
186 ADD_FAILURE() << "Expected ResourceHostMsg_RequestResource message";
187 return -1;
189 ResourceHostMsg_Request request = get<2>(params);
190 EXPECT_EQ(kTestPageUrl, request.url.spec());
191 message_queue_.erase(message_queue_.begin());
192 return get<1>(params);
195 void ConsumeFollowRedirect(int expected_request_id) {
196 ASSERT_FALSE(message_queue_.empty());
197 Tuple<int> args;
198 ASSERT_EQ(ResourceHostMsg_FollowRedirect::ID, message_queue_[0].type());
199 ASSERT_TRUE(ResourceHostMsg_FollowRedirect::Read(
200 &message_queue_[0], &args));
201 EXPECT_EQ(expected_request_id, get<0>(args));
202 message_queue_.erase(message_queue_.begin());
205 void ConsumeDataReceived_ACK(int expected_request_id) {
206 ASSERT_FALSE(message_queue_.empty());
207 Tuple<int> args;
208 ASSERT_EQ(ResourceHostMsg_DataReceived_ACK::ID, message_queue_[0].type());
209 ASSERT_TRUE(ResourceHostMsg_DataReceived_ACK::Read(
210 &message_queue_[0], &args));
211 EXPECT_EQ(expected_request_id, get<0>(args));
212 message_queue_.erase(message_queue_.begin());
215 void ConsumeDataDownloaded_ACK(int expected_request_id) {
216 ASSERT_FALSE(message_queue_.empty());
217 Tuple<int> args;
218 ASSERT_EQ(ResourceHostMsg_DataDownloaded_ACK::ID, message_queue_[0].type());
219 ASSERT_TRUE(ResourceHostMsg_DataDownloaded_ACK::Read(
220 &message_queue_[0], &args));
221 EXPECT_EQ(expected_request_id, get<0>(args));
222 message_queue_.erase(message_queue_.begin());
225 void ConsumeReleaseDownloadedFile(int expected_request_id) {
226 ASSERT_FALSE(message_queue_.empty());
227 Tuple<int> args;
228 ASSERT_EQ(ResourceHostMsg_ReleaseDownloadedFile::ID,
229 message_queue_[0].type());
230 ASSERT_TRUE(ResourceHostMsg_ReleaseDownloadedFile::Read(
231 &message_queue_[0], &args));
232 EXPECT_EQ(expected_request_id, get<0>(args));
233 message_queue_.erase(message_queue_.begin());
236 void ConsumeCancelRequest(int expected_request_id) {
237 ASSERT_FALSE(message_queue_.empty());
238 Tuple<int> args;
239 ASSERT_EQ(ResourceHostMsg_CancelRequest::ID, message_queue_[0].type());
240 ASSERT_TRUE(ResourceHostMsg_CancelRequest::Read(
241 &message_queue_[0], &args));
242 EXPECT_EQ(expected_request_id, get<0>(args));
243 message_queue_.erase(message_queue_.begin());
246 void NotifyReceivedRedirect(int request_id) {
247 ResourceResponseHead head;
248 std::string raw_headers(kTestRedirectHeaders);
249 std::replace(raw_headers.begin(), raw_headers.end(), '\n', '\0');
250 head.headers = new net::HttpResponseHeaders(raw_headers);
251 net::RedirectInfo redirect_info;
252 redirect_info.status_code = 302;
253 redirect_info.new_method = "GET";
254 redirect_info.new_url = GURL(kTestPageUrl);
255 redirect_info.new_first_party_for_cookies = GURL(kTestPageUrl);
256 EXPECT_EQ(true, dispatcher_.OnMessageReceived(
257 ResourceMsg_ReceivedRedirect(request_id, redirect_info, head)));
260 void NotifyReceivedResponse(int request_id) {
261 ResourceResponseHead head;
262 std::string raw_headers(kTestPageHeaders);
263 std::replace(raw_headers.begin(), raw_headers.end(), '\n', '\0');
264 head.headers = new net::HttpResponseHeaders(raw_headers);
265 head.mime_type = kTestPageMimeType;
266 head.charset = kTestPageCharset;
267 EXPECT_EQ(true,
268 dispatcher_.OnMessageReceived(
269 ResourceMsg_ReceivedResponse(request_id, head)));
272 void NotifySetDataBuffer(int request_id, size_t buffer_size) {
273 base::SharedMemory* shared_memory = new base::SharedMemory();
274 ASSERT_FALSE(shared_memory_map_[request_id]);
275 shared_memory_map_[request_id] = shared_memory;
276 EXPECT_TRUE(shared_memory->CreateAndMapAnonymous(buffer_size));
278 base::SharedMemoryHandle duplicate_handle;
279 EXPECT_TRUE(shared_memory->ShareToProcess(base::GetCurrentProcessHandle(),
280 &duplicate_handle));
281 EXPECT_TRUE(dispatcher_.OnMessageReceived(
282 ResourceMsg_SetDataBuffer(request_id, duplicate_handle,
283 shared_memory->requested_size(), 0)));
286 void NotifyDataReceived(int request_id, std::string data) {
287 ASSERT_LE(data.length(), shared_memory_map_[request_id]->requested_size());
288 memcpy(shared_memory_map_[request_id]->memory(), data.c_str(),
289 data.length());
291 EXPECT_TRUE(dispatcher_.OnMessageReceived(
292 ResourceMsg_DataReceived(request_id, 0, data.length(), data.length())));
295 void NotifyDataDownloaded(int request_id, int decoded_length,
296 int encoded_length) {
297 EXPECT_TRUE(dispatcher_.OnMessageReceived(
298 ResourceMsg_DataDownloaded(request_id, decoded_length,
299 encoded_length)));
302 void NotifyRequestComplete(int request_id, size_t total_size) {
303 ResourceMsg_RequestCompleteData request_complete_data;
304 request_complete_data.error_code = net::OK;
305 request_complete_data.was_ignored_by_handler = false;
306 request_complete_data.exists_in_cache = false;
307 request_complete_data.encoded_data_length = total_size;
308 EXPECT_TRUE(dispatcher_.OnMessageReceived(
309 ResourceMsg_RequestComplete(request_id, request_complete_data)));
312 RequestInfo* CreateRequestInfo(bool download_to_file) {
313 RequestInfo* request_info = new RequestInfo();
314 request_info->method = "GET";
315 request_info->url = GURL(kTestPageUrl);
316 request_info->first_party_for_cookies = GURL(kTestPageUrl);
317 request_info->referrer = Referrer();
318 request_info->headers = std::string();
319 request_info->load_flags = 0;
320 request_info->requestor_pid = 0;
321 request_info->request_type = RESOURCE_TYPE_SUB_RESOURCE;
322 request_info->appcache_host_id = kAppCacheNoHostId;
323 request_info->should_reset_appcache = false;
324 request_info->routing_id = 0;
325 request_info->download_to_file = download_to_file;
326 RequestExtraData extra_data;
328 return request_info;
331 ResourceDispatcher* dispatcher() { return &dispatcher_; }
333 private:
334 // Map of request IDs to shared memory.
335 std::map<int, base::SharedMemory*> shared_memory_map_;
337 std::vector<IPC::Message> message_queue_;
338 base::MessageLoop message_loop_;
339 ResourceDispatcher dispatcher_;
342 // Does a simple request and tests that the correct data is received. Simulates
343 // two reads.
344 TEST_F(ResourceDispatcherTest, RoundTrip) {
345 // Number of bytes received in the first read.
346 const size_t kFirstReceiveSize = 2;
347 ASSERT_LT(kFirstReceiveSize, strlen(kTestPageContents));
349 scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false));
350 TestRequestPeer peer(dispatcher());
351 int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer);
352 peer.set_request_id(request_id);
354 int id = ConsumeRequestResource();
355 EXPECT_EQ(0u, queued_messages());
357 NotifyReceivedResponse(id);
358 EXPECT_EQ(0u, queued_messages());
359 EXPECT_TRUE(peer.received_response());
361 NotifySetDataBuffer(id, strlen(kTestPageContents));
362 NotifyDataReceived(id, std::string(kTestPageContents, kFirstReceiveSize));
363 ConsumeDataReceived_ACK(id);
364 EXPECT_EQ(0u, queued_messages());
366 NotifyDataReceived(id, kTestPageContents + kFirstReceiveSize);
367 ConsumeDataReceived_ACK(id);
368 EXPECT_EQ(0u, queued_messages());
370 NotifyRequestComplete(id, strlen(kTestPageContents));
371 EXPECT_EQ(kTestPageContents, peer.data());
372 EXPECT_TRUE(peer.complete());
373 EXPECT_EQ(0u, queued_messages());
376 // Tests that the request IDs are straight when there are two interleaving
377 // requests.
378 TEST_F(ResourceDispatcherTest, MultipleRequests) {
379 const char kTestPageContents2[] = "Not kTestPageContents";
381 scoped_ptr<RequestInfo> request_info1(CreateRequestInfo(false));
382 TestRequestPeer peer1(dispatcher());
383 int request_id1 = dispatcher()->StartAsync(
384 *request_info1.get(), NULL, &peer1);
385 peer1.set_request_id(request_id1);
386 scoped_ptr<RequestInfo> request_info2(CreateRequestInfo(false));
387 TestRequestPeer peer2(dispatcher());
388 int request_id2 = dispatcher()->StartAsync(
389 *request_info1.get(), NULL, &peer2);
390 peer2.set_request_id(request_id2);
392 int id1 = ConsumeRequestResource();
393 int id2 = ConsumeRequestResource();
394 EXPECT_EQ(0u, queued_messages());
396 NotifyReceivedResponse(id1);
397 EXPECT_TRUE(peer1.received_response());
398 EXPECT_FALSE(peer2.received_response());
399 NotifyReceivedResponse(id2);
400 EXPECT_TRUE(peer2.received_response());
401 EXPECT_EQ(0u, queued_messages());
403 NotifySetDataBuffer(id2, strlen(kTestPageContents2));
404 NotifyDataReceived(id2, kTestPageContents2);
405 ConsumeDataReceived_ACK(id2);
406 NotifySetDataBuffer(id1, strlen(kTestPageContents));
407 NotifyDataReceived(id1, kTestPageContents);
408 ConsumeDataReceived_ACK(id1);
409 EXPECT_EQ(0u, queued_messages());
411 NotifyRequestComplete(id1, strlen(kTestPageContents));
412 EXPECT_EQ(kTestPageContents, peer1.data());
413 EXPECT_TRUE(peer1.complete());
414 EXPECT_FALSE(peer2.complete());
416 NotifyRequestComplete(id2, strlen(kTestPageContents2));
417 EXPECT_EQ(kTestPageContents2, peer2.data());
418 EXPECT_TRUE(peer2.complete());
420 EXPECT_EQ(0u, queued_messages());
423 // Tests that the cancel method prevents other messages from being received.
424 TEST_F(ResourceDispatcherTest, Cancel) {
425 scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false));
426 TestRequestPeer peer(dispatcher());
427 int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer);
428 peer.set_request_id(request_id);
430 int id = ConsumeRequestResource();
431 EXPECT_EQ(0u, queued_messages());
433 // Cancel the request.
434 dispatcher()->Cancel(request_id);
435 ConsumeCancelRequest(id);
437 // Any future messages related to the request should be ignored.
438 NotifyReceivedResponse(id);
439 NotifySetDataBuffer(id, strlen(kTestPageContents));
440 NotifyDataReceived(id, kTestPageContents);
441 NotifyRequestComplete(id, strlen(kTestPageContents));
443 EXPECT_EQ(0u, queued_messages());
444 EXPECT_EQ("", peer.data());
445 EXPECT_FALSE(peer.received_response());
446 EXPECT_FALSE(peer.complete());
449 // Tests that calling cancel during a callback works as expected.
450 TEST_F(ResourceDispatcherTest, CancelDuringCallback) {
451 scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false));
452 TestRequestPeer peer(dispatcher());
453 int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer);
454 peer.set_request_id(request_id);
455 peer.set_cancel_on_receive_response(true);
457 int id = ConsumeRequestResource();
458 EXPECT_EQ(0u, queued_messages());
460 NotifyReceivedResponse(id);
461 EXPECT_TRUE(peer.received_response());
462 // Request should have been cancelled.
463 ConsumeCancelRequest(id);
465 // Any future messages related to the request should be ignored.
466 NotifySetDataBuffer(id, strlen(kTestPageContents));
467 NotifyDataReceived(id, kTestPageContents);
468 NotifyRequestComplete(id, strlen(kTestPageContents));
470 EXPECT_EQ(0u, queued_messages());
471 EXPECT_EQ("", peer.data());
472 EXPECT_FALSE(peer.complete());
475 // Checks that redirects work as expected.
476 TEST_F(ResourceDispatcherTest, Redirect) {
477 scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false));
478 TestRequestPeer peer(dispatcher());
479 int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer);
480 peer.set_request_id(request_id);
482 int id = ConsumeRequestResource();
484 NotifyReceivedRedirect(id);
485 ConsumeFollowRedirect(id);
486 EXPECT_EQ(1, peer.seen_redirects());
488 NotifyReceivedRedirect(id);
489 ConsumeFollowRedirect(id);
490 EXPECT_EQ(2, peer.seen_redirects());
492 NotifyReceivedResponse(id);
493 EXPECT_TRUE(peer.received_response());
495 NotifySetDataBuffer(id, strlen(kTestPageContents));
496 NotifyDataReceived(id, kTestPageContents);
497 ConsumeDataReceived_ACK(id);
499 NotifyRequestComplete(id, strlen(kTestPageContents));
500 EXPECT_EQ(kTestPageContents, peer.data());
501 EXPECT_TRUE(peer.complete());
502 EXPECT_EQ(0u, queued_messages());
503 EXPECT_EQ(2, peer.seen_redirects());
506 // Tests that that cancelling during a redirect method prevents other messages
507 // from being received.
508 TEST_F(ResourceDispatcherTest, CancelDuringRedirect) {
509 scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false));
510 TestRequestPeer peer(dispatcher());
511 int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer);
512 peer.set_request_id(request_id);
513 peer.set_follow_redirects(false);
515 int id = ConsumeRequestResource();
516 EXPECT_EQ(0u, queued_messages());
518 // Redirect the request, which triggers a cancellation.
519 NotifyReceivedRedirect(id);
520 ConsumeCancelRequest(id);
521 EXPECT_EQ(1, peer.seen_redirects());
522 EXPECT_EQ(0u, queued_messages());
524 // Any future messages related to the request should be ignored. In practice,
525 // only the NotifyRequestComplete should be received after this point.
526 NotifyReceivedRedirect(id);
527 NotifyReceivedResponse(id);
528 NotifySetDataBuffer(id, strlen(kTestPageContents));
529 NotifyDataReceived(id, kTestPageContents);
530 NotifyRequestComplete(id, strlen(kTestPageContents));
532 EXPECT_EQ(0u, queued_messages());
533 EXPECT_EQ("", peer.data());
534 EXPECT_FALSE(peer.complete());
535 EXPECT_EQ(1, peer.seen_redirects());
538 // Checks that deferring a request delays messages until it's resumed.
539 TEST_F(ResourceDispatcherTest, Defer) {
540 scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false));
541 TestRequestPeer peer(dispatcher());
542 int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer);
543 peer.set_request_id(request_id);
545 int id = ConsumeRequestResource();
546 EXPECT_EQ(0u, queued_messages());
548 dispatcher()->SetDefersLoading(request_id, true);
549 NotifyReceivedResponse(id);
550 NotifySetDataBuffer(id, strlen(kTestPageContents));
551 NotifyDataReceived(id, kTestPageContents);
552 NotifyRequestComplete(id, strlen(kTestPageContents));
554 // None of the messages should have been processed yet, so no queued messages
555 // to the browser process, and no data received by the peer.
556 EXPECT_EQ(0u, queued_messages());
557 EXPECT_EQ("", peer.data());
558 EXPECT_FALSE(peer.complete());
559 EXPECT_EQ(0, peer.seen_redirects());
561 // Resuming the request should asynchronously unleash the deferred messages.
562 dispatcher()->SetDefersLoading(request_id, false);
563 base::RunLoop().RunUntilIdle();
565 ConsumeDataReceived_ACK(id);
566 EXPECT_EQ(0u, queued_messages());
567 EXPECT_TRUE(peer.received_response());
568 EXPECT_EQ(kTestPageContents, peer.data());
569 EXPECT_TRUE(peer.complete());
572 // Checks that deferring a request during a redirect delays messages until it's
573 // resumed.
574 TEST_F(ResourceDispatcherTest, DeferOnRedirect) {
575 scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false));
576 TestRequestPeer peer(dispatcher());
577 int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer);
578 peer.set_request_id(request_id);
579 peer.set_defer_on_redirect(true);
581 int id = ConsumeRequestResource();
582 EXPECT_EQ(0u, queued_messages());
584 // The request should be deferred during the redirect, including the message
585 // to follow the redirect.
586 NotifyReceivedRedirect(id);
587 NotifyReceivedResponse(id);
588 NotifySetDataBuffer(id, strlen(kTestPageContents));
589 NotifyDataReceived(id, kTestPageContents);
590 NotifyRequestComplete(id, strlen(kTestPageContents));
592 // None of the messages should have been processed yet, so no queued messages
593 // to the browser process, and no data received by the peer.
594 EXPECT_EQ(0u, queued_messages());
595 EXPECT_EQ("", peer.data());
596 EXPECT_FALSE(peer.complete());
597 EXPECT_EQ(1, peer.seen_redirects());
599 // Resuming the request should asynchronously unleash the deferred messages.
600 dispatcher()->SetDefersLoading(request_id, false);
601 base::RunLoop().RunUntilIdle();
603 ConsumeFollowRedirect(id);
604 ConsumeDataReceived_ACK(id);
606 EXPECT_EQ(0u, queued_messages());
607 EXPECT_TRUE(peer.received_response());
608 EXPECT_EQ(kTestPageContents, peer.data());
609 EXPECT_TRUE(peer.complete());
610 EXPECT_EQ(1, peer.seen_redirects());
613 // Checks that a deferred request that's cancelled doesn't receive any messages.
614 TEST_F(ResourceDispatcherTest, CancelDeferredRequest) {
615 scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false));
616 TestRequestPeer peer(dispatcher());
617 int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer);
618 peer.set_request_id(request_id);
620 int id = ConsumeRequestResource();
621 EXPECT_EQ(0u, queued_messages());
623 dispatcher()->SetDefersLoading(request_id, true);
624 NotifyReceivedRedirect(id);
625 dispatcher()->Cancel(request_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<RequestInfo> request_info(CreateRequestInfo(true));
640 TestRequestPeer peer(dispatcher());
641 int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer);
642 peer.set_request_id(request_id);
643 const int kDownloadedIncrement = 100;
644 const int kEncodedIncrement = 50;
646 int id = ConsumeRequestResource();
647 EXPECT_EQ(0u, queued_messages());
649 NotifyReceivedResponse(id);
650 EXPECT_EQ(0u, queued_messages());
651 EXPECT_TRUE(peer.received_response());
653 int expected_total_downloaded_length = 0;
654 int expected_total_encoded_length = 0;
655 for (int i = 0; i < 10; ++i) {
656 NotifyDataDownloaded(id, kDownloadedIncrement, kEncodedIncrement);
657 ConsumeDataDownloaded_ACK(id);
658 expected_total_downloaded_length += kDownloadedIncrement;
659 expected_total_encoded_length += kEncodedIncrement;
660 EXPECT_EQ(expected_total_downloaded_length,
661 peer.total_downloaded_data_length());
662 EXPECT_EQ(expected_total_encoded_length, peer.total_encoded_data_length());
665 NotifyRequestComplete(id, strlen(kTestPageContents));
666 EXPECT_EQ("", peer.data());
667 EXPECT_TRUE(peer.complete());
668 EXPECT_EQ(0u, queued_messages());
670 dispatcher()->RemovePendingRequest(request_id);
671 ConsumeReleaseDownloadedFile(id);
672 EXPECT_EQ(0u, queued_messages());
673 EXPECT_EQ(expected_total_downloaded_length,
674 peer.total_downloaded_data_length());
675 EXPECT_EQ(expected_total_encoded_length, peer.total_encoded_data_length());
678 // Make sure that when a download to file is cancelled, the file is destroyed.
679 TEST_F(ResourceDispatcherTest, CancelDownloadToFile) {
680 scoped_ptr<RequestInfo> request_info(CreateRequestInfo(true));
681 TestRequestPeer peer(dispatcher());
682 int request_id = dispatcher()->StartAsync(*request_info.get(), NULL, &peer);
683 peer.set_request_id(request_id);
685 int id = ConsumeRequestResource();
686 EXPECT_EQ(0u, queued_messages());
688 NotifyReceivedResponse(id);
689 EXPECT_EQ(0u, queued_messages());
690 EXPECT_TRUE(peer.received_response());
692 // Cancelling the request deletes the file.
693 dispatcher()->Cancel(request_id);
694 ConsumeCancelRequest(id);
695 ConsumeReleaseDownloadedFile(id);
698 TEST_F(ResourceDispatcherTest, Cookies) {
699 // FIXME
702 TEST_F(ResourceDispatcherTest, SerializedPostData) {
703 // FIXME
706 class TimeConversionTest : public ResourceDispatcherTest,
707 public RequestPeer {
708 public:
709 bool Send(IPC::Message* msg) override {
710 delete msg;
711 return true;
714 void PerformTest(const ResourceResponseHead& response_head) {
715 scoped_ptr<RequestInfo> request_info(CreateRequestInfo(false));
716 TestRequestPeer peer(dispatcher());
717 dispatcher()->StartAsync(*request_info.get(), NULL, &peer);
719 dispatcher()->OnMessageReceived(
720 ResourceMsg_ReceivedResponse(0, response_head));
723 // RequestPeer methods.
724 void OnUploadProgress(uint64 position, uint64 size) override {}
726 bool OnReceivedRedirect(const net::RedirectInfo& redirect_info,
727 const ResourceResponseInfo& info) override {
728 return true;
731 void OnReceivedResponse(const ResourceResponseInfo& info) override {
732 response_info_ = info;
735 void OnDownloadedData(int len, int encoded_data_length) override {}
737 void OnReceivedData(const char* data,
738 int data_length,
739 int encoded_data_length) override {}
741 void OnCompletedRequest(int error_code,
742 bool was_ignored_by_handler,
743 bool stale_copy_in_cache,
744 const std::string& security_info,
745 const base::TimeTicks& completion_time,
746 int64 total_transfer_size) override {}
748 const ResourceResponseInfo& response_info() const { return response_info_; }
750 private:
751 ResourceResponseInfo response_info_;
754 // TODO(simonjam): Enable this when 10829031 lands.
755 TEST_F(TimeConversionTest, DISABLED_ProperlyInitialized) {
756 ResourceResponseHead response_head;
757 response_head.request_start = base::TimeTicks::FromInternalValue(5);
758 response_head.response_start = base::TimeTicks::FromInternalValue(15);
759 response_head.load_timing.request_start_time = base::Time::Now();
760 response_head.load_timing.request_start =
761 base::TimeTicks::FromInternalValue(10);
762 response_head.load_timing.connect_timing.connect_start =
763 base::TimeTicks::FromInternalValue(13);
765 PerformTest(response_head);
767 EXPECT_LT(base::TimeTicks(), response_info().load_timing.request_start);
768 EXPECT_EQ(base::TimeTicks(),
769 response_info().load_timing.connect_timing.dns_start);
770 EXPECT_LE(response_head.load_timing.request_start,
771 response_info().load_timing.connect_timing.connect_start);
774 TEST_F(TimeConversionTest, PartiallyInitialized) {
775 ResourceResponseHead response_head;
776 response_head.request_start = base::TimeTicks::FromInternalValue(5);
777 response_head.response_start = base::TimeTicks::FromInternalValue(15);
779 PerformTest(response_head);
781 EXPECT_EQ(base::TimeTicks(), response_info().load_timing.request_start);
782 EXPECT_EQ(base::TimeTicks(),
783 response_info().load_timing.connect_timing.dns_start);
786 TEST_F(TimeConversionTest, NotInitialized) {
787 ResourceResponseHead response_head;
789 PerformTest(response_head);
791 EXPECT_EQ(base::TimeTicks(), response_info().load_timing.request_start);
792 EXPECT_EQ(base::TimeTicks(),
793 response_info().load_timing.connect_timing.dns_start);
796 } // namespace content