Home | History | Annotate | Download | only in child
      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.
      4 
      5 #include <string>
      6 #include <vector>
      7 
      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/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"
     26 #include "webkit/child/resource_loader_bridge.h"
     27 #include "webkit/common/appcache/appcache_interfaces.h"
     28 
     29 using webkit_glue::ResourceLoaderBridge;
     30 
     31 namespace content {
     32 
     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";
     42 
     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) {
     57   }
     58 
     59   virtual void OnUploadProgress(uint64 position, uint64 size) OVERRIDE {
     60   }
     61 
     62   virtual bool OnReceivedRedirect(const GURL& new_url,
     63                                   const GURL& new_first_party_for_cookies,
     64                                   const ResourceResponseInfo& info) OVERRIDE {
     65     ++seen_redirects_;
     66     if (defer_on_redirect_)
     67       bridge_->SetDefersLoading(true);
     68     return follow_redirects_;
     69   }
     70 
     71   virtual void OnReceivedResponse(const ResourceResponseInfo& info) OVERRIDE {
     72     EXPECT_FALSE(received_response_);
     73     received_response_ = true;
     74     if (cancel_on_receive_response_)
     75       bridge_->Cancel();
     76   }
     77 
     78   virtual void OnDownloadedData(int len, int encoded_data_length) OVERRIDE {
     79     total_downloaded_data_length_ += len;
     80     total_encoded_data_length_ += encoded_data_length;
     81   }
     82 
     83   virtual void OnReceivedData(const char* data,
     84                               int data_length,
     85                               int encoded_data_length) OVERRIDE {
     86     EXPECT_TRUE(received_response_);
     87     EXPECT_FALSE(complete_);
     88     data_.append(data, data_length);
     89     total_encoded_data_length_ += encoded_data_length;
     90   }
     91 
     92   virtual void OnCompletedRequest(
     93       int error_code,
     94       bool was_ignored_by_handler,
     95       bool stale_copy_in_cache,
     96       const std::string& security_info,
     97       const base::TimeTicks& completion_time,
     98       int64 total_transfer_size) OVERRIDE {
     99     EXPECT_TRUE(received_response_);
    100     EXPECT_FALSE(complete_);
    101     complete_ = true;
    102   }
    103 
    104   void set_follow_redirects(bool follow_redirects) {
    105     follow_redirects_ = follow_redirects;
    106   }
    107 
    108   void set_defer_on_redirect(bool defer_on_redirect) {
    109     defer_on_redirect_ = defer_on_redirect;
    110   }
    111 
    112   void set_cancel_on_receive_response(bool cancel_on_receive_response) {
    113     cancel_on_receive_response_ = cancel_on_receive_response;
    114   }
    115 
    116   int seen_redirects() const { return seen_redirects_; }
    117 
    118   bool received_response() const { return received_response_; }
    119 
    120   const std::string& data() const {
    121     return data_;
    122   }
    123   int total_encoded_data_length() const {
    124     return total_encoded_data_length_;
    125   }
    126   int total_downloaded_data_length() const {
    127     return total_downloaded_data_length_;
    128   }
    129 
    130   bool complete() const { return complete_; }
    131 
    132  private:
    133   // True if should follow redirects, false if should cancel them.
    134   bool follow_redirects_;
    135   // True if the request should be deferred on redirects.
    136   bool defer_on_redirect_;
    137   // Number of total redirects seen.
    138   int seen_redirects_;
    139 
    140   bool cancel_on_receive_response_;
    141   bool received_response_;
    142 
    143   // Data received.   If downloading to file, remains empty.
    144   std::string data_;
    145   // Total encoded data length, regardless of whether downloading to a file or
    146   // not.
    147   int total_encoded_data_length_;
    148   // Total length when downloading to a file.
    149   int total_downloaded_data_length_;
    150 
    151   bool complete_;
    152 
    153   ResourceLoaderBridge* bridge_;
    154 
    155   DISALLOW_COPY_AND_ASSIGN(TestRequestPeer);
    156 };
    157 
    158 // Sets up the message sender override for the unit test.
    159 class ResourceDispatcherTest : public testing::Test, public IPC::Sender {
    160  public:
    161   ResourceDispatcherTest() : dispatcher_(this) {}
    162 
    163   virtual ~ResourceDispatcherTest() {
    164     STLDeleteContainerPairSecondPointers(shared_memory_map_.begin(),
    165                                          shared_memory_map_.end());
    166   }
    167 
    168   // Emulates IPC send operations (IPC::Sender) by adding
    169   // pending messages to the queue.
    170   virtual bool Send(IPC::Message* msg) OVERRIDE {
    171     message_queue_.push_back(IPC::Message(*msg));
    172     delete msg;
    173     return true;
    174   }
    175 
    176   size_t queued_messages() const { return message_queue_.size(); }
    177 
    178   // Returns the ID of the consumed request.  Can't make assumptions about the
    179   // ID, because numbering is based on a global.
    180   int ConsumeRequestResource() {
    181     if (message_queue_.empty()) {
    182       ADD_FAILURE() << "Missing resource request message";
    183       return -1;
    184     }
    185 
    186     ResourceHostMsg_RequestResource::Param params;
    187     if (ResourceHostMsg_RequestResource::ID != message_queue_[0].type() ||
    188         !ResourceHostMsg_RequestResource::Read(&message_queue_[0], &params)) {
    189       ADD_FAILURE() << "Expected ResourceHostMsg_RequestResource message";
    190       return -1;
    191     }
    192     ResourceHostMsg_Request request = params.c;
    193     EXPECT_EQ(kTestPageUrl, request.url.spec());
    194     message_queue_.erase(message_queue_.begin());
    195     return params.b;
    196   }
    197 
    198   void ConsumeFollowRedirect(int expected_request_id) {
    199     ASSERT_FALSE(message_queue_.empty());
    200     Tuple1<int> args;
    201     ASSERT_EQ(ResourceHostMsg_FollowRedirect::ID, message_queue_[0].type());
    202     ASSERT_TRUE(ResourceHostMsg_FollowRedirect::Read(
    203         &message_queue_[0], &args));
    204     EXPECT_EQ(expected_request_id, args.a);
    205     message_queue_.erase(message_queue_.begin());
    206   }
    207 
    208   void ConsumeDataReceived_ACK(int expected_request_id) {
    209     ASSERT_FALSE(message_queue_.empty());
    210     Tuple1<int> args;
    211     ASSERT_EQ(ResourceHostMsg_DataReceived_ACK::ID, message_queue_[0].type());
    212     ASSERT_TRUE(ResourceHostMsg_DataReceived_ACK::Read(
    213         &message_queue_[0], &args));
    214     EXPECT_EQ(expected_request_id, args.a);
    215     message_queue_.erase(message_queue_.begin());
    216   }
    217 
    218   void ConsumeDataDownloaded_ACK(int expected_request_id) {
    219     ASSERT_FALSE(message_queue_.empty());
    220     Tuple1<int> args;
    221     ASSERT_EQ(ResourceHostMsg_DataDownloaded_ACK::ID, message_queue_[0].type());
    222     ASSERT_TRUE(ResourceHostMsg_DataDownloaded_ACK::Read(
    223         &message_queue_[0], &args));
    224     EXPECT_EQ(expected_request_id, args.a);
    225     message_queue_.erase(message_queue_.begin());
    226   }
    227 
    228   void ConsumeReleaseDownloadedFile(int expected_request_id) {
    229     ASSERT_FALSE(message_queue_.empty());
    230     Tuple1<int> args;
    231     ASSERT_EQ(ResourceHostMsg_ReleaseDownloadedFile::ID,
    232               message_queue_[0].type());
    233     ASSERT_TRUE(ResourceHostMsg_ReleaseDownloadedFile::Read(
    234         &message_queue_[0], &args));
    235     EXPECT_EQ(expected_request_id, args.a);
    236     message_queue_.erase(message_queue_.begin());
    237   }
    238 
    239   void ConsumeCancelRequest(int expected_request_id) {
    240     ASSERT_FALSE(message_queue_.empty());
    241     Tuple1<int> args;
    242     ASSERT_EQ(ResourceHostMsg_CancelRequest::ID, message_queue_[0].type());
    243     ASSERT_TRUE(ResourceHostMsg_CancelRequest::Read(
    244         &message_queue_[0], &args));
    245     EXPECT_EQ(expected_request_id, args.a);
    246     message_queue_.erase(message_queue_.begin());
    247   }
    248 
    249   void NotifyReceivedRedirect(int request_id) {
    250     ResourceResponseHead head;
    251     std::string raw_headers(kTestRedirectHeaders);
    252     std::replace(raw_headers.begin(), raw_headers.end(), '\n', '\0');
    253     head.headers = new net::HttpResponseHeaders(raw_headers);
    254     head.error_code = net::OK;
    255     EXPECT_EQ(true, dispatcher_.OnMessageReceived(
    256         ResourceMsg_ReceivedRedirect(request_id, GURL(kTestPageUrl),
    257                                      GURL(kTestPageUrl), head)));
    258   }
    259 
    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     head.error_code = net::OK;
    268     EXPECT_EQ(true,
    269               dispatcher_.OnMessageReceived(
    270                   ResourceMsg_ReceivedResponse(request_id, head)));
    271   }
    272 
    273   void NotifySetDataBuffer(int request_id, size_t buffer_size) {
    274     base::SharedMemory* shared_memory = new base::SharedMemory();
    275     ASSERT_FALSE(shared_memory_map_[request_id]);
    276     shared_memory_map_[request_id] = shared_memory;
    277     EXPECT_TRUE(shared_memory->CreateAndMapAnonymous(buffer_size));
    278 
    279     base::SharedMemoryHandle duplicate_handle;
    280     EXPECT_TRUE(shared_memory->ShareToProcess(
    281         base::Process::Current().handle(), &duplicate_handle));
    282     EXPECT_TRUE(dispatcher_.OnMessageReceived(
    283         ResourceMsg_SetDataBuffer(request_id, duplicate_handle,
    284                                   shared_memory->requested_size(), 0)));
    285   }
    286 
    287   void NotifyDataReceived(int request_id, std::string data) {
    288     ASSERT_LE(data.length(), shared_memory_map_[request_id]->requested_size());
    289     memcpy(shared_memory_map_[request_id]->memory(), data.c_str(),
    290            data.length());
    291 
    292     EXPECT_TRUE(dispatcher_.OnMessageReceived(
    293         ResourceMsg_DataReceived(request_id, 0, data.length(), data.length())));
    294   }
    295 
    296   void NotifyDataDownloaded(int request_id, int decoded_length,
    297                             int encoded_length) {
    298     EXPECT_TRUE(dispatcher_.OnMessageReceived(
    299         ResourceMsg_DataDownloaded(request_id, decoded_length,
    300                                    encoded_length)));
    301   }
    302 
    303   void NotifyRequestComplete(int request_id, size_t total_size) {
    304     ResourceMsg_RequestCompleteData request_complete_data;
    305     request_complete_data.error_code = net::OK;
    306     request_complete_data.was_ignored_by_handler = false;
    307     request_complete_data.exists_in_cache = false;
    308     request_complete_data.encoded_data_length = total_size;
    309     EXPECT_TRUE(dispatcher_.OnMessageReceived(
    310         ResourceMsg_RequestComplete(request_id, request_complete_data)));
    311   }
    312 
    313   ResourceLoaderBridge* CreateBridge() {
    314     return CreateBridgeInternal(false);
    315   }
    316 
    317   ResourceLoaderBridge* CreateBridgeForDownloadToFile() {
    318     return CreateBridgeInternal(true);
    319   }
    320 
    321   ResourceDispatcher* dispatcher() { return &dispatcher_; }
    322 
    323  private:
    324   ResourceLoaderBridge* CreateBridgeInternal(bool download_to_file) {
    325     RequestInfo request_info;
    326     request_info.method = "GET";
    327     request_info.url = GURL(kTestPageUrl);
    328     request_info.first_party_for_cookies = GURL(kTestPageUrl);
    329     request_info.referrer = GURL();
    330     request_info.headers = std::string();
    331     request_info.load_flags = 0;
    332     request_info.requestor_pid = 0;
    333     request_info.request_type = ResourceType::SUB_RESOURCE;
    334     request_info.appcache_host_id = appcache::kAppCacheNoHostId;
    335     request_info.routing_id = 0;
    336     request_info.download_to_file = download_to_file;
    337     RequestExtraData extra_data;
    338     request_info.extra_data = &extra_data;
    339 
    340     return dispatcher_.CreateBridge(request_info);
    341   }
    342 
    343   // Map of request IDs to shared memory.
    344   std::map<int, base::SharedMemory*> shared_memory_map_;
    345 
    346   std::vector<IPC::Message> message_queue_;
    347   ResourceDispatcher dispatcher_;
    348   base::MessageLoop message_loop_;
    349 };
    350 
    351 // Does a simple request and tests that the correct data is received.  Simulates
    352 // two reads.
    353 TEST_F(ResourceDispatcherTest, RoundTrip) {
    354   // Number of bytes received in the first read.
    355   const size_t kFirstReceiveSize = 2;
    356   ASSERT_LT(kFirstReceiveSize, strlen(kTestPageContents));
    357 
    358   scoped_ptr<ResourceLoaderBridge> bridge(CreateBridge());
    359   TestRequestPeer peer(bridge.get());
    360 
    361   EXPECT_TRUE(bridge->Start(&peer));
    362   int id = ConsumeRequestResource();
    363   EXPECT_EQ(0u, queued_messages());
    364 
    365   NotifyReceivedResponse(id);
    366   EXPECT_EQ(0u, queued_messages());
    367   EXPECT_TRUE(peer.received_response());
    368 
    369   NotifySetDataBuffer(id, strlen(kTestPageContents));
    370   NotifyDataReceived(id, std::string(kTestPageContents, kFirstReceiveSize));
    371   ConsumeDataReceived_ACK(id);
    372   EXPECT_EQ(0u, queued_messages());
    373 
    374   NotifyDataReceived(id, kTestPageContents + kFirstReceiveSize);
    375   ConsumeDataReceived_ACK(id);
    376   EXPECT_EQ(0u, queued_messages());
    377 
    378   NotifyRequestComplete(id, strlen(kTestPageContents));
    379   EXPECT_EQ(kTestPageContents, peer.data());
    380   EXPECT_TRUE(peer.complete());
    381   EXPECT_EQ(0u, queued_messages());
    382 }
    383 
    384 // Tests that the request IDs are straight when there are two interleaving
    385 // requests.
    386 TEST_F(ResourceDispatcherTest, MultipleRequests) {
    387   const char kTestPageContents2[] = "Not kTestPageContents";
    388 
    389   scoped_ptr<ResourceLoaderBridge> bridge1(CreateBridge());
    390   TestRequestPeer peer1(bridge1.get());
    391   scoped_ptr<ResourceLoaderBridge> bridge2(CreateBridge());
    392   TestRequestPeer peer2(bridge2.get());
    393 
    394   EXPECT_TRUE(bridge1->Start(&peer1));
    395   int id1 = ConsumeRequestResource();
    396   EXPECT_TRUE(bridge2->Start(&peer2));
    397   int id2 = ConsumeRequestResource();
    398   EXPECT_EQ(0u, queued_messages());
    399 
    400   NotifyReceivedResponse(id1);
    401   EXPECT_TRUE(peer1.received_response());
    402   EXPECT_FALSE(peer2.received_response());
    403   NotifyReceivedResponse(id2);
    404   EXPECT_TRUE(peer2.received_response());
    405   EXPECT_EQ(0u, queued_messages());
    406 
    407   NotifySetDataBuffer(id2, strlen(kTestPageContents2));
    408   NotifyDataReceived(id2, kTestPageContents2);
    409   ConsumeDataReceived_ACK(id2);
    410   NotifySetDataBuffer(id1, strlen(kTestPageContents));
    411   NotifyDataReceived(id1, kTestPageContents);
    412   ConsumeDataReceived_ACK(id1);
    413   EXPECT_EQ(0u, queued_messages());
    414 
    415   NotifyRequestComplete(id1, strlen(kTestPageContents));
    416   EXPECT_EQ(kTestPageContents, peer1.data());
    417   EXPECT_TRUE(peer1.complete());
    418   EXPECT_FALSE(peer2.complete());
    419 
    420   NotifyRequestComplete(id2, strlen(kTestPageContents2));
    421   EXPECT_EQ(kTestPageContents2, peer2.data());
    422   EXPECT_TRUE(peer2.complete());
    423 
    424   EXPECT_EQ(0u, queued_messages());
    425 }
    426 
    427 // Tests that the cancel method prevents other messages from being received.
    428 TEST_F(ResourceDispatcherTest, Cancel) {
    429   scoped_ptr<ResourceLoaderBridge> bridge(CreateBridge());
    430   TestRequestPeer peer(bridge.get());
    431 
    432   EXPECT_TRUE(bridge->Start(&peer));
    433   int id = ConsumeRequestResource();
    434   EXPECT_EQ(0u, queued_messages());
    435 
    436   // Cancel the request.
    437   bridge->Cancel();
    438   ConsumeCancelRequest(id);
    439 
    440   // Any future messages related to the request should be ignored.
    441   NotifyReceivedResponse(id);
    442   NotifySetDataBuffer(id, strlen(kTestPageContents));
    443   NotifyDataReceived(id, kTestPageContents);
    444   NotifyRequestComplete(id, strlen(kTestPageContents));
    445 
    446   EXPECT_EQ(0u, queued_messages());
    447   EXPECT_EQ("", peer.data());
    448   EXPECT_FALSE(peer.received_response());
    449   EXPECT_FALSE(peer.complete());
    450 }
    451 
    452 // Tests that calling cancel during a callback works as expected.
    453 TEST_F(ResourceDispatcherTest, CancelDuringCallback) {
    454   scoped_ptr<ResourceLoaderBridge> bridge(CreateBridge());
    455   TestRequestPeer peer(bridge.get());
    456   peer.set_cancel_on_receive_response(true);
    457 
    458   EXPECT_TRUE(bridge->Start(&peer));
    459   int id = ConsumeRequestResource();
    460   EXPECT_EQ(0u, queued_messages());
    461 
    462   NotifyReceivedResponse(id);
    463   EXPECT_TRUE(peer.received_response());
    464   // Request should have been cancelled.
    465   ConsumeCancelRequest(id);
    466 
    467   // Any future messages related to the request should be ignored.
    468   NotifySetDataBuffer(id, strlen(kTestPageContents));
    469   NotifyDataReceived(id, kTestPageContents);
    470   NotifyRequestComplete(id, strlen(kTestPageContents));
    471 
    472   EXPECT_EQ(0u, queued_messages());
    473   EXPECT_EQ("", peer.data());
    474   EXPECT_FALSE(peer.complete());
    475 }
    476 
    477 // Checks that redirects work as expected.
    478 TEST_F(ResourceDispatcherTest, Redirect) {
    479   scoped_ptr<ResourceLoaderBridge> bridge(CreateBridge());
    480   TestRequestPeer peer(bridge.get());
    481 
    482   EXPECT_TRUE(bridge->Start(&peer));
    483   int id = ConsumeRequestResource();
    484 
    485   NotifyReceivedRedirect(id);
    486   ConsumeFollowRedirect(id);
    487   EXPECT_EQ(1, peer.seen_redirects());
    488 
    489   NotifyReceivedRedirect(id);
    490   ConsumeFollowRedirect(id);
    491   EXPECT_EQ(2, peer.seen_redirects());
    492 
    493   NotifyReceivedResponse(id);
    494   EXPECT_TRUE(peer.received_response());
    495 
    496   NotifySetDataBuffer(id, strlen(kTestPageContents));
    497   NotifyDataReceived(id, kTestPageContents);
    498   ConsumeDataReceived_ACK(id);
    499 
    500   NotifyRequestComplete(id, strlen(kTestPageContents));
    501   EXPECT_EQ(kTestPageContents, peer.data());
    502   EXPECT_TRUE(peer.complete());
    503   EXPECT_EQ(0u, queued_messages());
    504   EXPECT_EQ(2, peer.seen_redirects());
    505 }
    506 
    507 // Tests that that cancelling during a redirect method prevents other messages
    508 // from being received.
    509 TEST_F(ResourceDispatcherTest, CancelDuringRedirect) {
    510   scoped_ptr<ResourceLoaderBridge> bridge(CreateBridge());
    511   TestRequestPeer peer(bridge.get());
    512   peer.set_follow_redirects(false);
    513 
    514   EXPECT_TRUE(bridge->Start(&peer));
    515   int id = ConsumeRequestResource();
    516   EXPECT_EQ(0u, queued_messages());
    517 
    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());
    523 
    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));
    531 
    532   EXPECT_EQ(0u, queued_messages());
    533   EXPECT_EQ("", peer.data());
    534   EXPECT_FALSE(peer.complete());
    535   EXPECT_EQ(1, peer.seen_redirects());
    536 }
    537 
    538 // Checks that deferring a request delays messages until it's resumed.
    539 TEST_F(ResourceDispatcherTest, Defer) {
    540   scoped_ptr<ResourceLoaderBridge> bridge(CreateBridge());
    541   TestRequestPeer peer(bridge.get());
    542 
    543   EXPECT_TRUE(bridge->Start(&peer));
    544   int id = ConsumeRequestResource();
    545   EXPECT_EQ(0u, queued_messages());
    546 
    547   bridge->SetDefersLoading(true);
    548   NotifyReceivedResponse(id);
    549   NotifySetDataBuffer(id, strlen(kTestPageContents));
    550   NotifyDataReceived(id, kTestPageContents);
    551   NotifyRequestComplete(id, strlen(kTestPageContents));
    552 
    553   // None of the messages should have been processed yet, so no queued messages
    554   // to the browser process, and no data received by the peer.
    555   EXPECT_EQ(0u, queued_messages());
    556   EXPECT_EQ("", peer.data());
    557   EXPECT_FALSE(peer.complete());
    558   EXPECT_EQ(0, peer.seen_redirects());
    559 
    560   // Resuming the request should asynchronously unleash the deferred messages.
    561   bridge->SetDefersLoading(false);
    562   base::RunLoop().RunUntilIdle();
    563 
    564   ConsumeDataReceived_ACK(id);
    565   EXPECT_EQ(0u, queued_messages());
    566   EXPECT_TRUE(peer.received_response());
    567   EXPECT_EQ(kTestPageContents, peer.data());
    568   EXPECT_TRUE(peer.complete());
    569 }
    570 
    571 // Checks that deferring a request during a redirect delays messages until it's
    572 // resumed.
    573 TEST_F(ResourceDispatcherTest, DeferOnRedirect) {
    574   scoped_ptr<ResourceLoaderBridge> bridge(CreateBridge());
    575   TestRequestPeer peer(bridge.get());
    576   peer.set_defer_on_redirect(true);
    577 
    578   EXPECT_TRUE(bridge->Start(&peer));
    579   int id = ConsumeRequestResource();
    580   EXPECT_EQ(0u, queued_messages());
    581 
    582   // The request should be deferred during the redirect, including the message
    583   // to follow the redirect.
    584   NotifyReceivedRedirect(id);
    585   NotifyReceivedResponse(id);
    586   NotifySetDataBuffer(id, strlen(kTestPageContents));
    587   NotifyDataReceived(id, kTestPageContents);
    588   NotifyRequestComplete(id, strlen(kTestPageContents));
    589 
    590   // None of the messages should have been processed yet, so no queued messages
    591   // to the browser process, and no data received by the peer.
    592   EXPECT_EQ(0u, queued_messages());
    593   EXPECT_EQ("", peer.data());
    594   EXPECT_FALSE(peer.complete());
    595   EXPECT_EQ(1, peer.seen_redirects());
    596 
    597   // Resuming the request should asynchronously unleash the deferred messages.
    598   bridge->SetDefersLoading(false);
    599   base::RunLoop().RunUntilIdle();
    600 
    601   ConsumeFollowRedirect(id);
    602   ConsumeDataReceived_ACK(id);
    603 
    604   EXPECT_EQ(0u, queued_messages());
    605   EXPECT_TRUE(peer.received_response());
    606   EXPECT_EQ(kTestPageContents, peer.data());
    607   EXPECT_TRUE(peer.complete());
    608   EXPECT_EQ(1, peer.seen_redirects());
    609 }
    610 
    611 // Checks that a deferred request that's cancelled doesn't receive any messages.
    612 TEST_F(ResourceDispatcherTest, CancelDeferredRequest) {
    613   scoped_ptr<ResourceLoaderBridge> bridge(CreateBridge());
    614   TestRequestPeer peer(bridge.get());
    615 
    616   EXPECT_TRUE(bridge->Start(&peer));
    617   int id = ConsumeRequestResource();
    618   EXPECT_EQ(0u, queued_messages());
    619 
    620   bridge->SetDefersLoading(true);
    621   NotifyReceivedRedirect(id);
    622   bridge->Cancel();
    623   ConsumeCancelRequest(id);
    624 
    625   NotifyRequestComplete(id, 0);
    626   base::RunLoop().RunUntilIdle();
    627 
    628   // None of the messages should have been processed.
    629   EXPECT_EQ(0u, queued_messages());
    630   EXPECT_EQ("", peer.data());
    631   EXPECT_FALSE(peer.complete());
    632   EXPECT_EQ(0, peer.seen_redirects());
    633 }
    634 
    635 TEST_F(ResourceDispatcherTest, DownloadToFile) {
    636   scoped_ptr<ResourceLoaderBridge> bridge(CreateBridgeForDownloadToFile());
    637   TestRequestPeer peer(bridge.get());
    638   const int kDownloadedIncrement = 100;
    639   const int kEncodedIncrement = 50;
    640 
    641   EXPECT_TRUE(bridge->Start(&peer));
    642   int id = ConsumeRequestResource();
    643   EXPECT_EQ(0u, queued_messages());
    644 
    645   NotifyReceivedResponse(id);
    646   EXPECT_EQ(0u, queued_messages());
    647   EXPECT_TRUE(peer.received_response());
    648 
    649   int expected_total_downloaded_length = 0;
    650   int expected_total_encoded_length = 0;
    651   for (int i = 0; i < 10; ++i) {
    652     NotifyDataDownloaded(id, kDownloadedIncrement, kEncodedIncrement);
    653     ConsumeDataDownloaded_ACK(id);
    654     expected_total_downloaded_length += kDownloadedIncrement;
    655     expected_total_encoded_length += kEncodedIncrement;
    656     EXPECT_EQ(expected_total_downloaded_length,
    657               peer.total_downloaded_data_length());
    658     EXPECT_EQ(expected_total_encoded_length, peer.total_encoded_data_length());
    659   }
    660 
    661   NotifyRequestComplete(id, strlen(kTestPageContents));
    662   EXPECT_EQ("", peer.data());
    663   EXPECT_TRUE(peer.complete());
    664   EXPECT_EQ(0u, queued_messages());
    665 
    666   bridge.reset();
    667   ConsumeReleaseDownloadedFile(id);
    668   EXPECT_EQ(0u, queued_messages());
    669   EXPECT_EQ(expected_total_downloaded_length,
    670             peer.total_downloaded_data_length());
    671   EXPECT_EQ(expected_total_encoded_length, peer.total_encoded_data_length());
    672 }
    673 
    674 // Make sure that when a download to file is cancelled, the file is destroyed.
    675 TEST_F(ResourceDispatcherTest, CancelDownloadToFile) {
    676   scoped_ptr<ResourceLoaderBridge> bridge(CreateBridgeForDownloadToFile());
    677   TestRequestPeer peer(bridge.get());
    678 
    679   EXPECT_TRUE(bridge->Start(&peer));
    680   int id = ConsumeRequestResource();
    681   EXPECT_EQ(0u, queued_messages());
    682 
    683   NotifyReceivedResponse(id);
    684   EXPECT_EQ(0u, queued_messages());
    685   EXPECT_TRUE(peer.received_response());
    686 
    687   // Cancelling the request deletes the file.
    688   bridge->Cancel();
    689   ConsumeCancelRequest(id);
    690   ConsumeReleaseDownloadedFile(id);
    691 
    692   // Deleting the bridge shouldn't send another message to delete the file.
    693   bridge.reset();
    694   EXPECT_EQ(0u, queued_messages());
    695 }
    696 
    697 TEST_F(ResourceDispatcherTest, Cookies) {
    698   // FIXME
    699 }
    700 
    701 TEST_F(ResourceDispatcherTest, SerializedPostData) {
    702   // FIXME
    703 }
    704 
    705 class TimeConversionTest : public ResourceDispatcherTest,
    706                            public RequestPeer {
    707  public:
    708   virtual bool Send(IPC::Message* msg) OVERRIDE {
    709     delete msg;
    710     return true;
    711   }
    712 
    713   void PerformTest(const ResourceResponseHead& response_head) {
    714     scoped_ptr<ResourceLoaderBridge> bridge(CreateBridge());
    715     bridge->Start(this);
    716 
    717     dispatcher()->OnMessageReceived(
    718         ResourceMsg_ReceivedResponse(0, response_head));
    719   }
    720 
    721   // RequestPeer methods.
    722   virtual void OnUploadProgress(uint64 position, uint64 size) OVERRIDE {
    723   }
    724 
    725   virtual bool OnReceivedRedirect(const GURL& new_url,
    726                                   const GURL& new_first_party_for_cookies,
    727                                   const ResourceResponseInfo& info) OVERRIDE {
    728     return true;
    729   }
    730 
    731   virtual void OnReceivedResponse(const ResourceResponseInfo& info) OVERRIDE {
    732     response_info_ = info;
    733   }
    734 
    735   virtual void OnDownloadedData(int len, int encoded_data_length) OVERRIDE {
    736   }
    737 
    738   virtual void OnReceivedData(const char* data,
    739                               int data_length,
    740                               int encoded_data_length) OVERRIDE {
    741   }
    742 
    743   virtual void OnCompletedRequest(
    744       int error_code,
    745       bool was_ignored_by_handler,
    746       bool stale_copy_in_cache,
    747       const std::string& security_info,
    748       const base::TimeTicks& completion_time,
    749       int64 total_transfer_size) OVERRIDE {
    750   }
    751 
    752   const ResourceResponseInfo& response_info() const { return response_info_; }
    753 
    754  private:
    755   ResourceResponseInfo response_info_;
    756 };
    757 
    758 // TODO(simonjam): Enable this when 10829031 lands.
    759 TEST_F(TimeConversionTest, DISABLED_ProperlyInitialized) {
    760   ResourceResponseHead response_head;
    761   response_head.error_code = net::OK;
    762   response_head.request_start = base::TimeTicks::FromInternalValue(5);
    763   response_head.response_start = base::TimeTicks::FromInternalValue(15);
    764   response_head.load_timing.request_start_time = base::Time::Now();
    765   response_head.load_timing.request_start =
    766       base::TimeTicks::FromInternalValue(10);
    767   response_head.load_timing.connect_timing.connect_start =
    768       base::TimeTicks::FromInternalValue(13);
    769 
    770   PerformTest(response_head);
    771 
    772   EXPECT_LT(base::TimeTicks(), response_info().load_timing.request_start);
    773   EXPECT_EQ(base::TimeTicks(),
    774             response_info().load_timing.connect_timing.dns_start);
    775   EXPECT_LE(response_head.load_timing.request_start,
    776             response_info().load_timing.connect_timing.connect_start);
    777 }
    778 
    779 TEST_F(TimeConversionTest, PartiallyInitialized) {
    780   ResourceResponseHead response_head;
    781   response_head.error_code = net::OK;
    782   response_head.request_start = base::TimeTicks::FromInternalValue(5);
    783   response_head.response_start = base::TimeTicks::FromInternalValue(15);
    784 
    785   PerformTest(response_head);
    786 
    787   EXPECT_EQ(base::TimeTicks(), response_info().load_timing.request_start);
    788   EXPECT_EQ(base::TimeTicks(),
    789             response_info().load_timing.connect_timing.dns_start);
    790 }
    791 
    792 TEST_F(TimeConversionTest, NotInitialized) {
    793   ResourceResponseHead response_head;
    794   response_head.error_code = net::OK;
    795 
    796   PerformTest(response_head);
    797 
    798   EXPECT_EQ(base::TimeTicks(), response_info().load_timing.request_start);
    799   EXPECT_EQ(base::TimeTicks(),
    800             response_info().load_timing.connect_timing.dns_start);
    801 }
    802 
    803 }  // namespace content
    804