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/files/file_util.h"
      8 #include "base/files/scoped_temp_dir.h"
      9 #include "base/message_loop/message_loop_proxy.h"
     10 #include "base/run_loop.h"
     11 #include "net/base/io_buffer.h"
     12 #include "net/base/net_errors.h"
     13 #include "net/base/test_completion_callback.h"
     14 #include "testing/gtest/include/gtest/gtest.h"
     15 #include "testing/platform_test.h"
     16 
     17 namespace net {
     18 
     19 class UploadFileElementReaderTest : public PlatformTest {
     20  protected:
     21   virtual void SetUp() {
     22     PlatformTest::SetUp();
     23     // Some tests (*.ReadPartially) rely on bytes_.size() being even.
     24     const char kData[] = "123456789abcdefghi";
     25     bytes_.assign(kData, kData + arraysize(kData) - 1);
     26 
     27     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
     28 
     29     ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(),
     30                                                &temp_file_path_));
     31     ASSERT_EQ(
     32         static_cast<int>(bytes_.size()),
     33         base::WriteFile(temp_file_path_, &bytes_[0], bytes_.size()));
     34 
     35     reader_.reset(
     36         new UploadFileElementReader(base::MessageLoopProxy::current().get(),
     37                                     temp_file_path_,
     38                                     0,
     39                                     kuint64max,
     40                                     base::Time()));
     41     TestCompletionCallback callback;
     42     ASSERT_EQ(ERR_IO_PENDING, reader_->Init(callback.callback()));
     43     EXPECT_EQ(OK, callback.WaitForResult());
     44     EXPECT_EQ(bytes_.size(), reader_->GetContentLength());
     45     EXPECT_EQ(bytes_.size(), reader_->BytesRemaining());
     46     EXPECT_FALSE(reader_->IsInMemory());
     47   }
     48 
     49   virtual ~UploadFileElementReaderTest() {
     50     reader_.reset();
     51     base::RunLoop().RunUntilIdle();
     52   }
     53 
     54   std::vector<char> bytes_;
     55   scoped_ptr<UploadElementReader> reader_;
     56   base::ScopedTempDir temp_dir_;
     57   base::FilePath temp_file_path_;
     58 };
     59 
     60 TEST_F(UploadFileElementReaderTest, ReadPartially) {
     61   const size_t kHalfSize = bytes_.size() / 2;
     62   ASSERT_EQ(bytes_.size(), kHalfSize * 2);
     63   std::vector<char> buf(kHalfSize);
     64   scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]);
     65   TestCompletionCallback read_callback1;
     66   ASSERT_EQ(ERR_IO_PENDING,
     67             reader_->Read(
     68                 wrapped_buffer.get(), buf.size(), read_callback1.callback()));
     69   EXPECT_EQ(static_cast<int>(buf.size()), read_callback1.WaitForResult());
     70   EXPECT_EQ(bytes_.size() - buf.size(), reader_->BytesRemaining());
     71   EXPECT_EQ(std::vector<char>(bytes_.begin(), bytes_.begin() + kHalfSize), buf);
     72 
     73   TestCompletionCallback read_callback2;
     74   EXPECT_EQ(ERR_IO_PENDING,
     75             reader_->Read(
     76                 wrapped_buffer.get(), buf.size(), read_callback2.callback()));
     77   EXPECT_EQ(static_cast<int>(buf.size()), read_callback2.WaitForResult());
     78   EXPECT_EQ(0U, reader_->BytesRemaining());
     79   EXPECT_EQ(std::vector<char>(bytes_.begin() + kHalfSize, bytes_.end()), buf);
     80 }
     81 
     82 TEST_F(UploadFileElementReaderTest, ReadAll) {
     83   std::vector<char> buf(bytes_.size());
     84   scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]);
     85   TestCompletionCallback read_callback;
     86   ASSERT_EQ(ERR_IO_PENDING,
     87             reader_->Read(
     88                 wrapped_buffer.get(), buf.size(), read_callback.callback()));
     89   EXPECT_EQ(static_cast<int>(buf.size()), read_callback.WaitForResult());
     90   EXPECT_EQ(0U, reader_->BytesRemaining());
     91   EXPECT_EQ(bytes_, buf);
     92   // Try to read again.
     93   EXPECT_EQ(0,
     94             reader_->Read(
     95                 wrapped_buffer.get(), buf.size(), read_callback.callback()));
     96 }
     97 
     98 TEST_F(UploadFileElementReaderTest, ReadTooMuch) {
     99   const size_t kTooLargeSize = bytes_.size() * 2;
    100   std::vector<char> buf(kTooLargeSize);
    101   scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]);
    102   TestCompletionCallback read_callback;
    103   ASSERT_EQ(ERR_IO_PENDING,
    104             reader_->Read(
    105                 wrapped_buffer.get(), buf.size(), read_callback.callback()));
    106   EXPECT_EQ(static_cast<int>(bytes_.size()), read_callback.WaitForResult());
    107   EXPECT_EQ(0U, reader_->BytesRemaining());
    108   buf.resize(bytes_.size());  // Resize to compare.
    109   EXPECT_EQ(bytes_, buf);
    110 }
    111 
    112 TEST_F(UploadFileElementReaderTest, MultipleInit) {
    113   std::vector<char> buf(bytes_.size());
    114   scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]);
    115 
    116   // Read all.
    117   TestCompletionCallback read_callback1;
    118   ASSERT_EQ(ERR_IO_PENDING,
    119             reader_->Read(
    120                 wrapped_buffer.get(), buf.size(), read_callback1.callback()));
    121   EXPECT_EQ(static_cast<int>(buf.size()), read_callback1.WaitForResult());
    122   EXPECT_EQ(0U, reader_->BytesRemaining());
    123   EXPECT_EQ(bytes_, buf);
    124 
    125   // Call Init() again to reset the state.
    126   TestCompletionCallback init_callback;
    127   ASSERT_EQ(ERR_IO_PENDING, reader_->Init(init_callback.callback()));
    128   EXPECT_EQ(OK, init_callback.WaitForResult());
    129   EXPECT_EQ(bytes_.size(), reader_->GetContentLength());
    130   EXPECT_EQ(bytes_.size(), reader_->BytesRemaining());
    131 
    132   // Read again.
    133   TestCompletionCallback read_callback2;
    134   ASSERT_EQ(ERR_IO_PENDING,
    135             reader_->Read(
    136                 wrapped_buffer.get(), buf.size(), read_callback2.callback()));
    137   EXPECT_EQ(static_cast<int>(buf.size()), read_callback2.WaitForResult());
    138   EXPECT_EQ(0U, reader_->BytesRemaining());
    139   EXPECT_EQ(bytes_, buf);
    140 }
    141 
    142 TEST_F(UploadFileElementReaderTest, InitDuringAsyncOperation) {
    143   std::vector<char> buf(bytes_.size());
    144   scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]);
    145 
    146   // Start reading all.
    147   TestCompletionCallback read_callback1;
    148   EXPECT_EQ(ERR_IO_PENDING,
    149             reader_->Read(
    150                 wrapped_buffer.get(), buf.size(), read_callback1.callback()));
    151 
    152   // Call Init to cancel the previous read.
    153   TestCompletionCallback init_callback1;
    154   EXPECT_EQ(ERR_IO_PENDING, reader_->Init(init_callback1.callback()));
    155 
    156   // Call Init again to cancel the previous init.
    157   TestCompletionCallback init_callback2;
    158   EXPECT_EQ(ERR_IO_PENDING, reader_->Init(init_callback2.callback()));
    159   EXPECT_EQ(OK, init_callback2.WaitForResult());
    160   EXPECT_EQ(bytes_.size(), reader_->GetContentLength());
    161   EXPECT_EQ(bytes_.size(), reader_->BytesRemaining());
    162 
    163   // Read half.
    164   std::vector<char> buf2(bytes_.size() / 2);
    165   scoped_refptr<IOBuffer> wrapped_buffer2 = new WrappedIOBuffer(&buf2[0]);
    166   TestCompletionCallback read_callback2;
    167   EXPECT_EQ(ERR_IO_PENDING,
    168             reader_->Read(
    169                 wrapped_buffer2.get(), buf2.size(), read_callback2.callback()));
    170   EXPECT_EQ(static_cast<int>(buf2.size()), read_callback2.WaitForResult());
    171   EXPECT_EQ(bytes_.size() - buf2.size(), reader_->BytesRemaining());
    172   EXPECT_EQ(std::vector<char>(bytes_.begin(), bytes_.begin() + buf2.size()),
    173             buf2);
    174 
    175   // Make sure callbacks are not called for cancelled operations.
    176   EXPECT_FALSE(read_callback1.have_result());
    177   EXPECT_FALSE(init_callback1.have_result());
    178 }
    179 
    180 TEST_F(UploadFileElementReaderTest, Range) {
    181   const uint64 kOffset = 2;
    182   const uint64 kLength = bytes_.size() - kOffset * 3;
    183   reader_.reset(
    184       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
    185                                   temp_file_path_,
    186                                   kOffset,
    187                                   kLength,
    188                                   base::Time()));
    189   TestCompletionCallback init_callback;
    190   ASSERT_EQ(ERR_IO_PENDING, reader_->Init(init_callback.callback()));
    191   EXPECT_EQ(OK, init_callback.WaitForResult());
    192   EXPECT_EQ(kLength, reader_->GetContentLength());
    193   EXPECT_EQ(kLength, reader_->BytesRemaining());
    194   std::vector<char> buf(kLength);
    195   scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]);
    196   TestCompletionCallback read_callback;
    197   ASSERT_EQ(
    198       ERR_IO_PENDING,
    199       reader_->Read(wrapped_buffer.get(), kLength, read_callback.callback()));
    200   EXPECT_EQ(static_cast<int>(kLength), read_callback.WaitForResult());
    201   const std::vector<char> expected(bytes_.begin() + kOffset,
    202                                    bytes_.begin() + kOffset + kLength);
    203   EXPECT_EQ(expected, buf);
    204 }
    205 
    206 TEST_F(UploadFileElementReaderTest, FileChanged) {
    207   base::File::Info info;
    208   ASSERT_TRUE(base::GetFileInfo(temp_file_path_, &info));
    209 
    210   // Expect one second before the actual modification time to simulate change.
    211   const base::Time expected_modification_time =
    212       info.last_modified - base::TimeDelta::FromSeconds(1);
    213   reader_.reset(
    214       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
    215                                   temp_file_path_,
    216                                   0,
    217                                   kuint64max,
    218                                   expected_modification_time));
    219   TestCompletionCallback init_callback;
    220   ASSERT_EQ(ERR_IO_PENDING, reader_->Init(init_callback.callback()));
    221   EXPECT_EQ(ERR_UPLOAD_FILE_CHANGED, init_callback.WaitForResult());
    222 }
    223 
    224 TEST_F(UploadFileElementReaderTest, WrongPath) {
    225   const base::FilePath wrong_path(FILE_PATH_LITERAL("wrong_path"));
    226   reader_.reset(
    227       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
    228                                   wrong_path,
    229                                   0,
    230                                   kuint64max,
    231                                   base::Time()));
    232   TestCompletionCallback init_callback;
    233   ASSERT_EQ(ERR_IO_PENDING, reader_->Init(init_callback.callback()));
    234   EXPECT_EQ(ERR_FILE_NOT_FOUND, init_callback.WaitForResult());
    235 }
    236 
    237 }  // namespace net
    238