Home | History | Annotate | Download | only in loader
      1 // Copyright 2013 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 "content/browser/loader/upload_data_stream_builder.h"
      6 
      7 #include <algorithm>
      8 
      9 #include "base/file_util.h"
     10 #include "base/files/file_path.h"
     11 #include "base/message_loop/message_loop.h"
     12 #include "base/message_loop/message_loop_proxy.h"
     13 #include "base/time/time.h"
     14 #include "net/base/upload_bytes_element_reader.h"
     15 #include "net/base/upload_data_stream.h"
     16 #include "net/base/upload_file_element_reader.h"
     17 #include "testing/gtest/include/gtest/gtest.h"
     18 #include "url/gurl.h"
     19 #include "webkit/browser/blob/blob_storage_controller.h"
     20 #include "webkit/common/resource_request_body.h"
     21 
     22 using webkit_blob::BlobData;
     23 using webkit_blob::BlobStorageController;
     24 using webkit_glue::ResourceRequestBody;
     25 
     26 namespace content {
     27 namespace {
     28 
     29 bool AreElementsEqual(const net::UploadElementReader& reader,
     30                       const ResourceRequestBody::Element& element) {
     31   switch(element.type()) {
     32     case ResourceRequestBody::Element::TYPE_BYTES: {
     33       const net::UploadBytesElementReader* bytes_reader =
     34           reader.AsBytesReader();
     35       return bytes_reader &&
     36           element.length() == bytes_reader->length() &&
     37           std::equal(element.bytes(), element.bytes() + element.length(),
     38                      bytes_reader->bytes());
     39     }
     40     case ResourceRequestBody::Element::TYPE_FILE: {
     41       const net::UploadFileElementReader* file_reader = reader.AsFileReader();
     42       return file_reader &&
     43           file_reader->path() == element.path() &&
     44           file_reader->range_offset() == element.offset() &&
     45           file_reader->range_length() == element.length() &&
     46           file_reader->expected_modification_time() ==
     47           element.expected_modification_time();
     48       break;
     49     }
     50     default:
     51       NOTREACHED();
     52   }
     53   return false;
     54 }
     55 
     56 }  // namespace
     57 
     58 TEST(UploadDataStreamBuilderTest, CreateUploadDataStreamWithoutBlob) {
     59   base::MessageLoop message_loop;
     60   scoped_refptr<ResourceRequestBody> request_body = new ResourceRequestBody;
     61 
     62   const char kData[] = "123";
     63   const base::FilePath::StringType kFilePath = FILE_PATH_LITERAL("abc");
     64   const uint64 kFileOffset = 10U;
     65   const uint64 kFileLength = 100U;
     66   const base::Time kFileTime = base::Time::FromDoubleT(999);
     67   const int64 kIdentifier = 12345;
     68 
     69   request_body->AppendBytes(kData, arraysize(kData) - 1);
     70   request_body->AppendFileRange(base::FilePath(kFilePath),
     71                                 kFileOffset, kFileLength, kFileTime);
     72   request_body->set_identifier(kIdentifier);
     73 
     74   scoped_ptr<net::UploadDataStream> upload(UploadDataStreamBuilder::Build(
     75       request_body.get(), NULL, NULL, base::MessageLoopProxy::current().get()));
     76 
     77   EXPECT_EQ(kIdentifier, upload->identifier());
     78   ASSERT_EQ(request_body->elements()->size(), upload->element_readers().size());
     79 
     80   const net::UploadBytesElementReader* r1 =
     81       upload->element_readers()[0]->AsBytesReader();
     82   ASSERT_TRUE(r1);
     83   EXPECT_EQ(kData, std::string(r1->bytes(), r1->length()));
     84 
     85   const net::UploadFileElementReader* r2 =
     86       upload->element_readers()[1]->AsFileReader();
     87   ASSERT_TRUE(r2);
     88   EXPECT_EQ(kFilePath, r2->path().value());
     89   EXPECT_EQ(kFileOffset, r2->range_offset());
     90   EXPECT_EQ(kFileLength, r2->range_length());
     91   EXPECT_EQ(kFileTime, r2->expected_modification_time());
     92 }
     93 
     94 TEST(UploadDataStreamBuilderTest, ResolveBlobAndCreateUploadDataStream) {
     95   base::MessageLoop message_loop;
     96   // Setup blob data for testing.
     97   base::Time time1, time2;
     98   base::Time::FromString("Tue, 15 Nov 1994, 12:45:26 GMT", &time1);
     99   base::Time::FromString("Mon, 14 Nov 1994, 11:30:49 GMT", &time2);
    100 
    101   BlobStorageController blob_storage_controller;
    102   scoped_refptr<BlobData> blob_data(new BlobData());
    103 
    104   GURL blob_url0("blob://url_0");
    105   blob_storage_controller.AddFinishedBlob(blob_url0, blob_data.get());
    106 
    107   blob_data->AppendData("BlobData");
    108   blob_data->AppendFile(
    109       base::FilePath(FILE_PATH_LITERAL("BlobFile.txt")), 0, 20, time1);
    110 
    111   GURL blob_url1("blob://url_1");
    112   blob_storage_controller.AddFinishedBlob(blob_url1, blob_data.get());
    113 
    114   GURL blob_url2("blob://url_2");
    115   blob_storage_controller.CloneBlob(blob_url2, blob_url1);
    116 
    117   GURL blob_url3("blob://url_3");
    118   blob_storage_controller.CloneBlob(blob_url3, blob_url2);
    119 
    120   // Setup upload data elements for comparison.
    121   ResourceRequestBody::Element blob_element1, blob_element2;
    122   blob_element1.SetToBytes(
    123       blob_data->items().at(0).bytes() +
    124       static_cast<int>(blob_data->items().at(0).offset()),
    125       static_cast<int>(blob_data->items().at(0).length()));
    126   blob_element2.SetToFilePathRange(
    127       blob_data->items().at(1).path(),
    128       blob_data->items().at(1).offset(),
    129       blob_data->items().at(1).length(),
    130       blob_data->items().at(1).expected_modification_time());
    131 
    132   ResourceRequestBody::Element upload_element1, upload_element2;
    133   upload_element1.SetToBytes("Hello", 5);
    134   upload_element2.SetToFilePathRange(
    135       base::FilePath(FILE_PATH_LITERAL("foo1.txt")), 0, 20, time2);
    136 
    137   // Test no blob reference.
    138   scoped_refptr<ResourceRequestBody> request_body(new ResourceRequestBody());
    139   request_body->AppendBytes(upload_element1.bytes(), upload_element1.length());
    140   request_body->AppendFileRange(upload_element2.path(),
    141                                 upload_element2.offset(),
    142                                 upload_element2.length(),
    143                                 upload_element2.expected_modification_time());
    144 
    145   scoped_ptr<net::UploadDataStream> upload(
    146       UploadDataStreamBuilder::Build(request_body.get(),
    147                                      &blob_storage_controller,
    148                                      NULL,
    149                                      base::MessageLoopProxy::current().get()));
    150 
    151   ASSERT_EQ(2U, upload->element_readers().size());
    152   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[0], upload_element1));
    153   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[1], upload_element2));
    154 
    155   // Test having only one blob reference that refers to empty blob data.
    156   request_body = new ResourceRequestBody();
    157   request_body->AppendBlob(blob_url0);
    158 
    159   upload =
    160       UploadDataStreamBuilder::Build(request_body.get(),
    161                                      &blob_storage_controller,
    162                                      NULL,
    163                                      base::MessageLoopProxy::current().get());
    164   ASSERT_EQ(0U, upload->element_readers().size());
    165 
    166   // Test having only one blob reference.
    167   request_body = new ResourceRequestBody();
    168   request_body->AppendBlob(blob_url1);
    169 
    170   upload =
    171       UploadDataStreamBuilder::Build(request_body.get(),
    172                                      &blob_storage_controller,
    173                                      NULL,
    174                                      base::MessageLoopProxy::current().get());
    175   ASSERT_EQ(2U, upload->element_readers().size());
    176   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[0], blob_element1));
    177   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[1], blob_element2));
    178 
    179   // Test having one blob reference at the beginning.
    180   request_body = new ResourceRequestBody();
    181   request_body->AppendBlob(blob_url1);
    182   request_body->AppendBytes(upload_element1.bytes(), upload_element1.length());
    183   request_body->AppendFileRange(upload_element2.path(),
    184                                 upload_element2.offset(),
    185                                 upload_element2.length(),
    186                                 upload_element2.expected_modification_time());
    187 
    188   upload =
    189       UploadDataStreamBuilder::Build(request_body.get(),
    190                                      &blob_storage_controller,
    191                                      NULL,
    192                                      base::MessageLoopProxy::current().get());
    193   ASSERT_EQ(4U, upload->element_readers().size());
    194   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[0], blob_element1));
    195   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[1], blob_element2));
    196   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[2], upload_element1));
    197   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[3], upload_element2));
    198 
    199   // Test having one blob reference at the end.
    200   request_body = new ResourceRequestBody();
    201   request_body->AppendBytes(upload_element1.bytes(), upload_element1.length());
    202   request_body->AppendFileRange(upload_element2.path(),
    203                                 upload_element2.offset(),
    204                                 upload_element2.length(),
    205                                 upload_element2.expected_modification_time());
    206   request_body->AppendBlob(blob_url1);
    207 
    208   upload =
    209       UploadDataStreamBuilder::Build(request_body.get(),
    210                                      &blob_storage_controller,
    211                                      NULL,
    212                                      base::MessageLoopProxy::current().get());
    213   ASSERT_EQ(4U, upload->element_readers().size());
    214   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[0], upload_element1));
    215   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[1], upload_element2));
    216   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[2], blob_element1));
    217   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[3], blob_element2));
    218 
    219   // Test having one blob reference in the middle.
    220   request_body = new ResourceRequestBody();
    221   request_body->AppendBytes(upload_element1.bytes(), upload_element1.length());
    222   request_body->AppendBlob(blob_url1);
    223   request_body->AppendFileRange(upload_element2.path(),
    224                                 upload_element2.offset(),
    225                                 upload_element2.length(),
    226                                 upload_element2.expected_modification_time());
    227 
    228   upload =
    229       UploadDataStreamBuilder::Build(request_body.get(),
    230                                      &blob_storage_controller,
    231                                      NULL,
    232                                      base::MessageLoopProxy::current().get());
    233   ASSERT_EQ(4U, upload->element_readers().size());
    234   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[0], upload_element1));
    235   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[1], blob_element1));
    236   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[2], blob_element2));
    237   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[3], upload_element2));
    238 
    239   // Test having multiple blob references.
    240   request_body = new ResourceRequestBody();
    241   request_body->AppendBlob(blob_url1);
    242   request_body->AppendBytes(upload_element1.bytes(), upload_element1.length());
    243   request_body->AppendBlob(blob_url2);
    244   request_body->AppendBlob(blob_url3);
    245   request_body->AppendFileRange(upload_element2.path(),
    246                                 upload_element2.offset(),
    247                                 upload_element2.length(),
    248                                 upload_element2.expected_modification_time());
    249 
    250   upload =
    251       UploadDataStreamBuilder::Build(request_body.get(),
    252                                      &blob_storage_controller,
    253                                      NULL,
    254                                      base::MessageLoopProxy::current().get());
    255   ASSERT_EQ(8U, upload->element_readers().size());
    256   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[0], blob_element1));
    257   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[1], blob_element2));
    258   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[2], upload_element1));
    259   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[3], blob_element1));
    260   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[4], blob_element2));
    261   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[5], blob_element1));
    262   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[6], blob_element2));
    263   EXPECT_TRUE(AreElementsEqual(*upload->element_readers()[7], upload_element2));
    264 }
    265 
    266 }  // namespace content
    267