Home | History | Annotate | Download | only in base
      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 "net/base/upload_file_element_reader.h"
      6 
      7 #include "base/file_util.h"
      8 #include "base/files/scoped_temp_dir.h"
      9 #include "base/message_loop/message_loop_proxy.h"
     10 #include "net/base/io_buffer.h"
     11 #include "net/base/net_errors.h"
     12 #include "net/base/test_completion_callback.h"
     13 #include "testing/gtest/include/gtest/gtest.h"
     14 #include "testing/platform_test.h"
     15 
     16 namespace net {
     17 
     18 class UploadFileElementReaderTest : public PlatformTest {
     19  protected:
     20   virtual void SetUp() OVERRIDE {
     21     // Some tests (*.ReadPartially) rely on bytes_.size() being even.
     22     const char kData[] = "123456789abcdefghi";
     23     bytes_.assign(kData, kData + arraysize(kData) - 1);
     24 
     25     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
     26 
     27     ASSERT_TRUE(file_util::CreateTemporaryFileInDir(temp_dir_.path(),
     28                                                     &temp_file_path_));
     29     ASSERT_EQ(
     30         static_cast<int>(bytes_.size()),
     31         file_util::WriteFile(temp_file_path_, &bytes_[0], bytes_.size()));
     32 
     33     reader_.reset(
     34         new UploadFileElementReader(base::MessageLoopProxy::current().get(),
     35                                     temp_file_path_,
     36                                     0,
     37                                     kuint64max,
     38                                     base::Time()));
     39     TestCompletionCallback callback;
     40     ASSERT_EQ(ERR_IO_PENDING, reader_->Init(callback.callback()));
     41     EXPECT_EQ(OK, callback.WaitForResult());
     42     EXPECT_EQ(bytes_.size(), reader_->GetContentLength());
     43     EXPECT_EQ(bytes_.size(), reader_->BytesRemaining());
     44     EXPECT_FALSE(reader_->IsInMemory());
     45   }
     46 
     47   std::vector<char> bytes_;
     48   scoped_ptr<UploadElementReader> reader_;
     49   base::ScopedTempDir temp_dir_;
     50   base::FilePath temp_file_path_;
     51 };
     52 
     53 TEST_F(UploadFileElementReaderTest, ReadPartially) {
     54   const size_t kHalfSize = bytes_.size() / 2;
     55   ASSERT_EQ(bytes_.size(), kHalfSize * 2);
     56   std::vector<char> buf(kHalfSize);
     57   scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]);
     58   TestCompletionCallback read_callback1;
     59   ASSERT_EQ(ERR_IO_PENDING,
     60             reader_->Read(
     61                 wrapped_buffer.get(), buf.size(), read_callback1.callback()));
     62   EXPECT_EQ(static_cast<int>(buf.size()), read_callback1.WaitForResult());
     63   EXPECT_EQ(bytes_.size() - buf.size(), reader_->BytesRemaining());
     64   EXPECT_EQ(std::vector<char>(bytes_.begin(), bytes_.begin() + kHalfSize), buf);
     65 
     66   TestCompletionCallback read_callback2;
     67   EXPECT_EQ(ERR_IO_PENDING,
     68             reader_->Read(
     69                 wrapped_buffer.get(), buf.size(), read_callback2.callback()));
     70   EXPECT_EQ(static_cast<int>(buf.size()), read_callback2.WaitForResult());
     71   EXPECT_EQ(0U, reader_->BytesRemaining());
     72   EXPECT_EQ(std::vector<char>(bytes_.begin() + kHalfSize, bytes_.end()), buf);
     73 }
     74 
     75 TEST_F(UploadFileElementReaderTest, ReadAll) {
     76   std::vector<char> buf(bytes_.size());
     77   scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]);
     78   TestCompletionCallback read_callback;
     79   ASSERT_EQ(ERR_IO_PENDING,
     80             reader_->Read(
     81                 wrapped_buffer.get(), buf.size(), read_callback.callback()));
     82   EXPECT_EQ(static_cast<int>(buf.size()), read_callback.WaitForResult());
     83   EXPECT_EQ(0U, reader_->BytesRemaining());
     84   EXPECT_EQ(bytes_, buf);
     85   // Try to read again.
     86   EXPECT_EQ(0,
     87             reader_->Read(
     88                 wrapped_buffer.get(), buf.size(), read_callback.callback()));
     89 }
     90 
     91 TEST_F(UploadFileElementReaderTest, ReadTooMuch) {
     92   const size_t kTooLargeSize = bytes_.size() * 2;
     93   std::vector<char> buf(kTooLargeSize);
     94   scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]);
     95   TestCompletionCallback read_callback;
     96   ASSERT_EQ(ERR_IO_PENDING,
     97             reader_->Read(
     98                 wrapped_buffer.get(), buf.size(), read_callback.callback()));
     99   EXPECT_EQ(static_cast<int>(bytes_.size()), read_callback.WaitForResult());
    100   EXPECT_EQ(0U, reader_->BytesRemaining());
    101   buf.resize(bytes_.size());  // Resize to compare.
    102   EXPECT_EQ(bytes_, buf);
    103 }
    104 
    105 TEST_F(UploadFileElementReaderTest, MultipleInit) {
    106   std::vector<char> buf(bytes_.size());
    107   scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]);
    108 
    109   // Read all.
    110   TestCompletionCallback read_callback1;
    111   ASSERT_EQ(ERR_IO_PENDING,
    112             reader_->Read(
    113                 wrapped_buffer.get(), buf.size(), read_callback1.callback()));
    114   EXPECT_EQ(static_cast<int>(buf.size()), read_callback1.WaitForResult());
    115   EXPECT_EQ(0U, reader_->BytesRemaining());
    116   EXPECT_EQ(bytes_, buf);
    117 
    118   // Call Init() again to reset the state.
    119   TestCompletionCallback init_callback;
    120   ASSERT_EQ(ERR_IO_PENDING, reader_->Init(init_callback.callback()));
    121   EXPECT_EQ(OK, init_callback.WaitForResult());
    122   EXPECT_EQ(bytes_.size(), reader_->GetContentLength());
    123   EXPECT_EQ(bytes_.size(), reader_->BytesRemaining());
    124 
    125   // Read again.
    126   TestCompletionCallback read_callback2;
    127   ASSERT_EQ(ERR_IO_PENDING,
    128             reader_->Read(
    129                 wrapped_buffer.get(), buf.size(), read_callback2.callback()));
    130   EXPECT_EQ(static_cast<int>(buf.size()), read_callback2.WaitForResult());
    131   EXPECT_EQ(0U, reader_->BytesRemaining());
    132   EXPECT_EQ(bytes_, buf);
    133 }
    134 
    135 TEST_F(UploadFileElementReaderTest, InitDuringAsyncOperation) {
    136   std::vector<char> buf(bytes_.size());
    137   scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]);
    138 
    139   // Start reading all.
    140   TestCompletionCallback read_callback1;
    141   EXPECT_EQ(ERR_IO_PENDING,
    142             reader_->Read(
    143                 wrapped_buffer.get(), buf.size(), read_callback1.callback()));
    144 
    145   // Call Init to cancel the previous read.
    146   TestCompletionCallback init_callback1;
    147   EXPECT_EQ(ERR_IO_PENDING, reader_->Init(init_callback1.callback()));
    148 
    149   // Call Init again to cancel the previous init.
    150   TestCompletionCallback init_callback2;
    151   EXPECT_EQ(ERR_IO_PENDING, reader_->Init(init_callback2.callback()));
    152   EXPECT_EQ(OK, init_callback2.WaitForResult());
    153   EXPECT_EQ(bytes_.size(), reader_->GetContentLength());
    154   EXPECT_EQ(bytes_.size(), reader_->BytesRemaining());
    155 
    156   // Read half.
    157   std::vector<char> buf2(bytes_.size() / 2);
    158   scoped_refptr<IOBuffer> wrapped_buffer2 = new WrappedIOBuffer(&buf2[0]);
    159   TestCompletionCallback read_callback2;
    160   EXPECT_EQ(ERR_IO_PENDING,
    161             reader_->Read(
    162                 wrapped_buffer2.get(), buf2.size(), read_callback2.callback()));
    163   EXPECT_EQ(static_cast<int>(buf2.size()), read_callback2.WaitForResult());
    164   EXPECT_EQ(bytes_.size() - buf2.size(), reader_->BytesRemaining());
    165   EXPECT_EQ(std::vector<char>(bytes_.begin(), bytes_.begin() + buf2.size()),
    166             buf2);
    167 
    168   // Make sure callbacks are not called for cancelled operations.
    169   EXPECT_FALSE(read_callback1.have_result());
    170   EXPECT_FALSE(init_callback1.have_result());
    171 }
    172 
    173 TEST_F(UploadFileElementReaderTest, Range) {
    174   const uint64 kOffset = 2;
    175   const uint64 kLength = bytes_.size() - kOffset * 3;
    176   reader_.reset(
    177       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
    178                                   temp_file_path_,
    179                                   kOffset,
    180                                   kLength,
    181                                   base::Time()));
    182   TestCompletionCallback init_callback;
    183   ASSERT_EQ(ERR_IO_PENDING, reader_->Init(init_callback.callback()));
    184   EXPECT_EQ(OK, init_callback.WaitForResult());
    185   EXPECT_EQ(kLength, reader_->GetContentLength());
    186   EXPECT_EQ(kLength, reader_->BytesRemaining());
    187   std::vector<char> buf(kLength);
    188   scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]);
    189   TestCompletionCallback read_callback;
    190   ASSERT_EQ(
    191       ERR_IO_PENDING,
    192       reader_->Read(wrapped_buffer.get(), kLength, read_callback.callback()));
    193   EXPECT_EQ(static_cast<int>(kLength), read_callback.WaitForResult());
    194   const std::vector<char> expected(bytes_.begin() + kOffset,
    195                                    bytes_.begin() + kOffset + kLength);
    196   EXPECT_EQ(expected, buf);
    197 }
    198 
    199 TEST_F(UploadFileElementReaderTest, FileChanged) {
    200   base::PlatformFileInfo info;
    201   ASSERT_TRUE(file_util::GetFileInfo(temp_file_path_, &info));
    202 
    203   // Expect one second before the actual modification time to simulate change.
    204   const base::Time expected_modification_time =
    205       info.last_modified - base::TimeDelta::FromSeconds(1);
    206   reader_.reset(
    207       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
    208                                   temp_file_path_,
    209                                   0,
    210                                   kuint64max,
    211                                   expected_modification_time));
    212   TestCompletionCallback init_callback;
    213   ASSERT_EQ(ERR_IO_PENDING, reader_->Init(init_callback.callback()));
    214   EXPECT_EQ(ERR_UPLOAD_FILE_CHANGED, init_callback.WaitForResult());
    215 }
    216 
    217 TEST_F(UploadFileElementReaderTest, WrongPath) {
    218   const base::FilePath wrong_path(FILE_PATH_LITERAL("wrong_path"));
    219   reader_.reset(
    220       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
    221                                   wrong_path,
    222                                   0,
    223                                   kuint64max,
    224                                   base::Time()));
    225   TestCompletionCallback init_callback;
    226   ASSERT_EQ(ERR_IO_PENDING, reader_->Init(init_callback.callback()));
    227   EXPECT_EQ(OK, init_callback.WaitForResult());
    228   EXPECT_EQ(0U, reader_->GetContentLength());
    229   EXPECT_EQ(0U, reader_->BytesRemaining());
    230 }
    231 
    232 
    233 class UploadFileElementReaderSyncTest : public PlatformTest {
    234  protected:
    235   virtual void SetUp() OVERRIDE {
    236     // Some tests (*.ReadPartially) rely on bytes_.size() being even.
    237     const char kData[] = "123456789abcdefghi";
    238     bytes_.assign(kData, kData + arraysize(kData) - 1);
    239 
    240     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    241 
    242     ASSERT_TRUE(file_util::CreateTemporaryFileInDir(temp_dir_.path(),
    243                                                     &temp_file_path_));
    244     ASSERT_EQ(
    245         static_cast<int>(bytes_.size()),
    246         file_util::WriteFile(temp_file_path_, &bytes_[0], bytes_.size()));
    247 
    248     reader_.reset(new UploadFileElementReaderSync(
    249         temp_file_path_, 0, kuint64max, base::Time()));
    250     ASSERT_EQ(OK, reader_->Init(CompletionCallback()));
    251     EXPECT_EQ(bytes_.size(), reader_->GetContentLength());
    252     EXPECT_EQ(bytes_.size(), reader_->BytesRemaining());
    253     EXPECT_FALSE(reader_->IsInMemory());
    254   }
    255 
    256   std::vector<char> bytes_;
    257   scoped_ptr<UploadElementReader> reader_;
    258   base::ScopedTempDir temp_dir_;
    259   base::FilePath temp_file_path_;
    260 };
    261 
    262 TEST_F(UploadFileElementReaderSyncTest, ReadPartially) {
    263   const size_t kHalfSize = bytes_.size() / 2;
    264   ASSERT_EQ(bytes_.size(), kHalfSize * 2);
    265   std::vector<char> buf(kHalfSize);
    266   scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]);
    267   EXPECT_EQ(
    268       static_cast<int>(buf.size()),
    269       reader_->Read(wrapped_buffer.get(), buf.size(), CompletionCallback()));
    270   EXPECT_EQ(bytes_.size() - buf.size(), reader_->BytesRemaining());
    271   EXPECT_EQ(std::vector<char>(bytes_.begin(), bytes_.begin() + kHalfSize), buf);
    272 
    273   EXPECT_EQ(
    274       static_cast<int>(buf.size()),
    275       reader_->Read(wrapped_buffer.get(), buf.size(), CompletionCallback()));
    276   EXPECT_EQ(0U, reader_->BytesRemaining());
    277   EXPECT_EQ(std::vector<char>(bytes_.begin() + kHalfSize, bytes_.end()), buf);
    278 }
    279 
    280 TEST_F(UploadFileElementReaderSyncTest, ReadAll) {
    281   std::vector<char> buf(bytes_.size());
    282   scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]);
    283   EXPECT_EQ(
    284       static_cast<int>(buf.size()),
    285       reader_->Read(wrapped_buffer.get(), buf.size(), CompletionCallback()));
    286   EXPECT_EQ(0U, reader_->BytesRemaining());
    287   EXPECT_EQ(bytes_, buf);
    288   // Try to read again.
    289   EXPECT_EQ(
    290       0, reader_->Read(wrapped_buffer.get(), buf.size(), CompletionCallback()));
    291 }
    292 
    293 TEST_F(UploadFileElementReaderSyncTest, ReadTooMuch) {
    294   const size_t kTooLargeSize = bytes_.size() * 2;
    295   std::vector<char> buf(kTooLargeSize);
    296   scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]);
    297   EXPECT_EQ(
    298       static_cast<int>(bytes_.size()),
    299       reader_->Read(wrapped_buffer.get(), buf.size(), CompletionCallback()));
    300   EXPECT_EQ(0U, reader_->BytesRemaining());
    301   buf.resize(bytes_.size());  // Resize to compare.
    302   EXPECT_EQ(bytes_, buf);
    303 }
    304 
    305 TEST_F(UploadFileElementReaderSyncTest, MultipleInit) {
    306   std::vector<char> buf(bytes_.size());
    307   scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]);
    308 
    309   // Read all.
    310   EXPECT_EQ(
    311       static_cast<int>(buf.size()),
    312       reader_->Read(wrapped_buffer.get(), buf.size(), CompletionCallback()));
    313   EXPECT_EQ(0U, reader_->BytesRemaining());
    314   EXPECT_EQ(bytes_, buf);
    315 
    316   // Call Init() again to reset the state.
    317   ASSERT_EQ(OK, reader_->Init(CompletionCallback()));
    318   EXPECT_EQ(bytes_.size(), reader_->GetContentLength());
    319   EXPECT_EQ(bytes_.size(), reader_->BytesRemaining());
    320 
    321   // Read again.
    322   EXPECT_EQ(
    323       static_cast<int>(buf.size()),
    324       reader_->Read(wrapped_buffer.get(), buf.size(), CompletionCallback()));
    325   EXPECT_EQ(0U, reader_->BytesRemaining());
    326   EXPECT_EQ(bytes_, buf);
    327 }
    328 
    329 TEST_F(UploadFileElementReaderSyncTest, Range) {
    330   const uint64 kOffset = 2;
    331   const uint64 kLength = bytes_.size() - kOffset * 3;
    332   reader_.reset(new UploadFileElementReaderSync(
    333       temp_file_path_, kOffset, kLength, base::Time()));
    334   ASSERT_EQ(OK, reader_->Init(CompletionCallback()));
    335   EXPECT_EQ(kLength, reader_->GetContentLength());
    336   EXPECT_EQ(kLength, reader_->BytesRemaining());
    337   std::vector<char> buf(kLength);
    338   scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]);
    339   EXPECT_EQ(static_cast<int>(kLength),
    340             reader_->Read(wrapped_buffer.get(), kLength, CompletionCallback()));
    341   const std::vector<char> expected(bytes_.begin() + kOffset,
    342                                    bytes_.begin() + kOffset + kLength);
    343   EXPECT_EQ(expected, buf);
    344 }
    345 
    346 TEST_F(UploadFileElementReaderSyncTest, FileChanged) {
    347   base::PlatformFileInfo info;
    348   ASSERT_TRUE(file_util::GetFileInfo(temp_file_path_, &info));
    349 
    350   // Expect one second before the actual modification time to simulate change.
    351   const base::Time expected_modification_time =
    352       info.last_modified - base::TimeDelta::FromSeconds(1);
    353   reader_.reset(new UploadFileElementReaderSync(
    354       temp_file_path_, 0, kuint64max, expected_modification_time));
    355   EXPECT_EQ(ERR_UPLOAD_FILE_CHANGED, reader_->Init(CompletionCallback()));
    356 }
    357 
    358 TEST_F(UploadFileElementReaderSyncTest, WrongPath) {
    359   const base::FilePath wrong_path(FILE_PATH_LITERAL("wrong_path"));
    360   reader_.reset(new UploadFileElementReaderSync(
    361       wrong_path, 0, kuint64max, base::Time()));
    362   ASSERT_EQ(OK, reader_->Init(CompletionCallback()));
    363   EXPECT_EQ(0U, reader_->GetContentLength());
    364   EXPECT_EQ(0U, reader_->BytesRemaining());
    365 }
    366 
    367 }  // namespace net
    368