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_data_stream.h"
      6 
      7 #include <algorithm>
      8 #include <vector>
      9 
     10 #include "base/basictypes.h"
     11 #include "base/bind.h"
     12 #include "base/file_util.h"
     13 #include "base/files/file_path.h"
     14 #include "base/files/scoped_temp_dir.h"
     15 #include "base/memory/scoped_ptr.h"
     16 #include "base/message_loop/message_loop.h"
     17 #include "base/run_loop.h"
     18 #include "base/time/time.h"
     19 #include "net/base/io_buffer.h"
     20 #include "net/base/net_errors.h"
     21 #include "net/base/test_completion_callback.h"
     22 #include "net/base/upload_bytes_element_reader.h"
     23 #include "net/base/upload_file_element_reader.h"
     24 #include "testing/gmock/include/gmock/gmock.h"
     25 #include "testing/gtest/include/gtest/gtest.h"
     26 #include "testing/platform_test.h"
     27 
     28 using ::testing::DoAll;
     29 using ::testing::Invoke;
     30 using ::testing::Return;
     31 using ::testing::_;
     32 
     33 namespace net {
     34 
     35 namespace {
     36 
     37 const char kTestData[] = "0123456789";
     38 const size_t kTestDataSize = arraysize(kTestData) - 1;
     39 const size_t kTestBufferSize = 1 << 14;  // 16KB.
     40 
     41 // Reads data from the upload data stream, and returns the data as string.
     42 std::string ReadFromUploadDataStream(UploadDataStream* stream) {
     43   std::string data_read;
     44   scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize);
     45   while (!stream->IsEOF()) {
     46     TestCompletionCallback callback;
     47     const int result =
     48         stream->Read(buf.get(), kTestBufferSize, callback.callback());
     49     const int bytes_read =
     50         result != ERR_IO_PENDING ? result : callback.WaitForResult();
     51     data_read.append(buf->data(), bytes_read);
     52   }
     53   return data_read;
     54 }
     55 
     56 // A mock class of UploadElementReader.
     57 class MockUploadElementReader : public UploadElementReader {
     58  public:
     59   MockUploadElementReader(int content_length, bool is_in_memory)
     60       : content_length_(content_length),
     61         bytes_remaining_(content_length),
     62         is_in_memory_(is_in_memory),
     63         init_result_(OK),
     64         read_result_(OK) {}
     65 
     66   virtual ~MockUploadElementReader() {}
     67 
     68   // UploadElementReader overrides.
     69   MOCK_METHOD1(Init, int(const CompletionCallback& callback));
     70   virtual uint64 GetContentLength() const OVERRIDE { return content_length_; }
     71   virtual uint64 BytesRemaining() const OVERRIDE { return bytes_remaining_; }
     72   virtual bool IsInMemory() const OVERRIDE { return is_in_memory_; }
     73   MOCK_METHOD3(Read, int(IOBuffer* buf,
     74                          int buf_length,
     75                          const CompletionCallback& callback));
     76 
     77   // Sets expectation to return the specified result from Init() asynchronously.
     78   void SetAsyncInitExpectation(int result) {
     79     init_result_ = result;
     80     EXPECT_CALL(*this, Init(_))
     81         .WillOnce(DoAll(Invoke(this, &MockUploadElementReader::OnInit),
     82                         Return(ERR_IO_PENDING)));
     83   }
     84 
     85   // Sets expectation to return the specified result from Read().
     86   void SetReadExpectation(int result) {
     87     read_result_ = result;
     88     EXPECT_CALL(*this, Read(_, _, _))
     89         .WillOnce(Invoke(this, &MockUploadElementReader::OnRead));
     90   }
     91 
     92  private:
     93   void OnInit(const CompletionCallback& callback) {
     94     base::MessageLoop::current()->PostTask(FROM_HERE,
     95                                            base::Bind(callback, init_result_));
     96   }
     97 
     98   int OnRead(IOBuffer* buf,
     99              int buf_length,
    100              const CompletionCallback& callback) {
    101     if (read_result_ > 0)
    102       bytes_remaining_ = std::max(0, bytes_remaining_ - read_result_);
    103     if (IsInMemory()) {
    104       return read_result_;
    105     } else {
    106       base::MessageLoop::current()->PostTask(
    107           FROM_HERE, base::Bind(callback, read_result_));
    108       return ERR_IO_PENDING;
    109     }
    110   }
    111 
    112   int content_length_;
    113   int bytes_remaining_;
    114   bool is_in_memory_;
    115 
    116   // Result value returned from Init().
    117   int init_result_;
    118 
    119   // Result value returned from Read().
    120   int read_result_;
    121 };
    122 
    123 }  // namespace
    124 
    125 class UploadDataStreamTest : public PlatformTest {
    126  public:
    127   virtual void SetUp() {
    128     PlatformTest::SetUp();
    129     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
    130   }
    131   virtual ~UploadDataStreamTest() {
    132     element_readers_.clear();
    133     base::RunLoop().RunUntilIdle();
    134   }
    135 
    136   void FileChangedHelper(const base::FilePath& file_path,
    137                          const base::Time& time,
    138                          bool error_expected);
    139 
    140   base::ScopedTempDir temp_dir_;
    141   ScopedVector<UploadElementReader> element_readers_;
    142 };
    143 
    144 TEST_F(UploadDataStreamTest, EmptyUploadData) {
    145   UploadDataStream stream(element_readers_.Pass(), 0);
    146   ASSERT_EQ(OK, stream.Init(CompletionCallback()));
    147   EXPECT_TRUE(stream.IsInMemory());
    148   EXPECT_EQ(0U, stream.size());
    149   EXPECT_EQ(0U, stream.position());
    150   EXPECT_TRUE(stream.IsEOF());
    151 }
    152 
    153 TEST_F(UploadDataStreamTest, ConsumeAllBytes) {
    154   element_readers_.push_back(new UploadBytesElementReader(
    155       kTestData, kTestDataSize));
    156   UploadDataStream stream(element_readers_.Pass(), 0);
    157   ASSERT_EQ(OK, stream.Init(CompletionCallback()));
    158   EXPECT_TRUE(stream.IsInMemory());
    159   EXPECT_EQ(kTestDataSize, stream.size());
    160   EXPECT_EQ(0U, stream.position());
    161   EXPECT_FALSE(stream.IsEOF());
    162   scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize);
    163   while (!stream.IsEOF()) {
    164     int bytes_read =
    165         stream.Read(buf.get(), kTestBufferSize, CompletionCallback());
    166     ASSERT_LE(0, bytes_read);  // Not an error.
    167   }
    168   EXPECT_EQ(kTestDataSize, stream.position());
    169   ASSERT_TRUE(stream.IsEOF());
    170 }
    171 
    172 TEST_F(UploadDataStreamTest, File) {
    173   base::FilePath temp_file_path;
    174   ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(),
    175                                              &temp_file_path));
    176   ASSERT_EQ(static_cast<int>(kTestDataSize),
    177             file_util::WriteFile(temp_file_path, kTestData, kTestDataSize));
    178 
    179   element_readers_.push_back(
    180       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
    181                                   temp_file_path,
    182                                   0,
    183                                   kuint64max,
    184                                   base::Time()));
    185 
    186   TestCompletionCallback init_callback;
    187   UploadDataStream stream(element_readers_.Pass(), 0);
    188   ASSERT_EQ(ERR_IO_PENDING, stream.Init(init_callback.callback()));
    189   ASSERT_EQ(OK, init_callback.WaitForResult());
    190   EXPECT_FALSE(stream.IsInMemory());
    191   EXPECT_EQ(kTestDataSize, stream.size());
    192   EXPECT_EQ(0U, stream.position());
    193   EXPECT_FALSE(stream.IsEOF());
    194   scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize);
    195   while (!stream.IsEOF()) {
    196     TestCompletionCallback read_callback;
    197     ASSERT_EQ(
    198         ERR_IO_PENDING,
    199         stream.Read(buf.get(), kTestBufferSize, read_callback.callback()));
    200     ASSERT_LE(0, read_callback.WaitForResult());  // Not an error.
    201   }
    202   EXPECT_EQ(kTestDataSize, stream.position());
    203   ASSERT_TRUE(stream.IsEOF());
    204 }
    205 
    206 TEST_F(UploadDataStreamTest, FileSmallerThanLength) {
    207   base::FilePath temp_file_path;
    208   ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(),
    209                                              &temp_file_path));
    210   ASSERT_EQ(static_cast<int>(kTestDataSize),
    211             file_util::WriteFile(temp_file_path, kTestData, kTestDataSize));
    212   const uint64 kFakeSize = kTestDataSize*2;
    213 
    214   UploadFileElementReader::ScopedOverridingContentLengthForTests
    215       overriding_content_length(kFakeSize);
    216 
    217   element_readers_.push_back(
    218       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
    219                                   temp_file_path,
    220                                   0,
    221                                   kuint64max,
    222                                   base::Time()));
    223 
    224   TestCompletionCallback init_callback;
    225   UploadDataStream stream(element_readers_.Pass(), 0);
    226   ASSERT_EQ(ERR_IO_PENDING, stream.Init(init_callback.callback()));
    227   ASSERT_EQ(OK, init_callback.WaitForResult());
    228   EXPECT_FALSE(stream.IsInMemory());
    229   EXPECT_EQ(kFakeSize, stream.size());
    230   EXPECT_EQ(0U, stream.position());
    231   EXPECT_FALSE(stream.IsEOF());
    232   uint64 read_counter = 0;
    233   scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize);
    234   while (!stream.IsEOF()) {
    235     TestCompletionCallback read_callback;
    236     ASSERT_EQ(
    237         ERR_IO_PENDING,
    238         stream.Read(buf.get(), kTestBufferSize, read_callback.callback()));
    239     int bytes_read = read_callback.WaitForResult();
    240     ASSERT_LE(0, bytes_read);  // Not an error.
    241     read_counter += bytes_read;
    242     EXPECT_EQ(read_counter, stream.position());
    243   }
    244   // UpdateDataStream will pad out the file with 0 bytes so that the HTTP
    245   // transaction doesn't hang.  Therefore we expected the full size.
    246   EXPECT_EQ(kFakeSize, read_counter);
    247   EXPECT_EQ(read_counter, stream.position());
    248 }
    249 
    250 TEST_F(UploadDataStreamTest, ReadErrorSync) {
    251   // This element cannot be read.
    252   MockUploadElementReader* reader =
    253       new MockUploadElementReader(kTestDataSize, true);
    254   EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK));
    255   reader->SetReadExpectation(ERR_FAILED);
    256   element_readers_.push_back(reader);
    257 
    258   // This element is ignored because of the error from the previous reader.
    259   element_readers_.push_back(new UploadBytesElementReader(
    260       kTestData, kTestDataSize));
    261 
    262   UploadDataStream stream(element_readers_.Pass(), 0);
    263 
    264   // Run Init().
    265   ASSERT_EQ(OK, stream.Init(CompletionCallback()));
    266   EXPECT_EQ(kTestDataSize*2, stream.size());
    267   EXPECT_EQ(0U, stream.position());
    268   EXPECT_FALSE(stream.IsEOF());
    269 
    270   // Prepare a buffer filled with non-zero data.
    271   scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize);
    272   std::fill_n(buf->data(), kTestBufferSize, -1);
    273 
    274   // Read() results in success even when the reader returns error.
    275   EXPECT_EQ(static_cast<int>(kTestDataSize * 2),
    276             stream.Read(buf.get(), kTestBufferSize, CompletionCallback()));
    277   EXPECT_EQ(kTestDataSize * 2, stream.position());
    278   EXPECT_TRUE(stream.IsEOF());
    279 
    280   // The buffer is filled with zero.
    281   EXPECT_EQ(static_cast<int>(kTestDataSize*2),
    282             std::count(buf->data(), buf->data() + kTestBufferSize, 0));
    283 }
    284 
    285 TEST_F(UploadDataStreamTest, ReadErrorAsync) {
    286   // This element cannot be read.
    287   MockUploadElementReader* reader =
    288       new MockUploadElementReader(kTestDataSize, false);
    289   reader->SetAsyncInitExpectation(OK);
    290   reader->SetReadExpectation(ERR_FAILED);
    291   element_readers_.push_back(reader);
    292 
    293   // This element is ignored because of the error from the previous reader.
    294   element_readers_.push_back(new UploadBytesElementReader(
    295       kTestData, kTestDataSize));
    296 
    297   UploadDataStream stream(element_readers_.Pass(), 0);
    298 
    299   // Run Init().
    300   TestCompletionCallback init_callback;
    301   ASSERT_EQ(ERR_IO_PENDING, stream.Init(init_callback.callback()));
    302   EXPECT_EQ(OK, init_callback.WaitForResult());
    303   EXPECT_EQ(kTestDataSize*2, stream.size());
    304   EXPECT_EQ(0U, stream.position());
    305   EXPECT_FALSE(stream.IsEOF());
    306 
    307   // Prepare a buffer filled with non-zero data.
    308   scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize);
    309   std::fill_n(buf->data(), kTestBufferSize, -1);
    310 
    311   // Read() results in success even when the reader returns error.
    312   TestCompletionCallback read_callback;
    313   ASSERT_EQ(ERR_IO_PENDING,
    314             stream.Read(buf.get(), kTestBufferSize, read_callback.callback()));
    315   EXPECT_EQ(static_cast<int>(kTestDataSize * 2), read_callback.WaitForResult());
    316   EXPECT_EQ(kTestDataSize*2, stream.position());
    317   EXPECT_TRUE(stream.IsEOF());
    318 
    319   // The buffer is filled with zero.
    320   EXPECT_EQ(static_cast<int>(kTestDataSize*2),
    321             std::count(buf->data(), buf->data() + kTestBufferSize, 0));
    322 }
    323 
    324 TEST_F(UploadDataStreamTest, FileAndBytes) {
    325   base::FilePath temp_file_path;
    326   ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(),
    327                                              &temp_file_path));
    328   ASSERT_EQ(static_cast<int>(kTestDataSize),
    329             file_util::WriteFile(temp_file_path, kTestData, kTestDataSize));
    330 
    331   const uint64 kFileRangeOffset = 1;
    332   const uint64 kFileRangeLength = 4;
    333   element_readers_.push_back(
    334       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
    335                                   temp_file_path,
    336                                   kFileRangeOffset,
    337                                   kFileRangeLength,
    338                                   base::Time()));
    339 
    340   element_readers_.push_back(new UploadBytesElementReader(
    341       kTestData, kTestDataSize));
    342 
    343   const uint64 kStreamSize = kTestDataSize + kFileRangeLength;
    344   TestCompletionCallback init_callback;
    345   UploadDataStream stream(element_readers_.Pass(), 0);
    346   ASSERT_EQ(ERR_IO_PENDING, stream.Init(init_callback.callback()));
    347   ASSERT_EQ(OK, init_callback.WaitForResult());
    348   EXPECT_FALSE(stream.IsInMemory());
    349   EXPECT_EQ(kStreamSize, stream.size());
    350   EXPECT_EQ(0U, stream.position());
    351   EXPECT_FALSE(stream.IsEOF());
    352   scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize);
    353   while (!stream.IsEOF()) {
    354     TestCompletionCallback read_callback;
    355     const int result =
    356         stream.Read(buf.get(), kTestBufferSize, read_callback.callback());
    357     const int bytes_read =
    358         result != ERR_IO_PENDING ? result : read_callback.WaitForResult();
    359     ASSERT_LE(0, bytes_read);  // Not an error.
    360   }
    361   EXPECT_EQ(kStreamSize, stream.position());
    362   ASSERT_TRUE(stream.IsEOF());
    363 }
    364 
    365 TEST_F(UploadDataStreamTest, Chunk) {
    366   const uint64 kStreamSize = kTestDataSize*2;
    367   UploadDataStream stream(UploadDataStream::CHUNKED, 0);
    368   stream.AppendChunk(kTestData, kTestDataSize, false);
    369   stream.AppendChunk(kTestData, kTestDataSize, true);
    370 
    371   ASSERT_EQ(OK, stream.Init(CompletionCallback()));
    372   EXPECT_FALSE(stream.IsInMemory());
    373   EXPECT_EQ(0U, stream.size());  // Content-Length is 0 for chunked data.
    374   EXPECT_EQ(0U, stream.position());
    375   EXPECT_FALSE(stream.IsEOF());
    376   scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize);
    377   while (!stream.IsEOF()) {
    378     int bytes_read =
    379         stream.Read(buf.get(), kTestBufferSize, CompletionCallback());
    380     ASSERT_LE(0, bytes_read);  // Not an error.
    381   }
    382   EXPECT_EQ(kStreamSize, stream.position());
    383   ASSERT_TRUE(stream.IsEOF());
    384 }
    385 
    386 // Init() with on-memory and not-on-memory readers.
    387 TEST_F(UploadDataStreamTest, InitAsync) {
    388   // Create UploadDataStream with mock readers.
    389   MockUploadElementReader* reader = NULL;
    390 
    391   reader = new MockUploadElementReader(kTestDataSize, true);
    392   EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK));
    393   element_readers_.push_back(reader);
    394 
    395   reader = new MockUploadElementReader(kTestDataSize, true);
    396   EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK));
    397   element_readers_.push_back(reader);
    398 
    399   reader = new MockUploadElementReader(kTestDataSize, false);
    400   reader->SetAsyncInitExpectation(OK);
    401   element_readers_.push_back(reader);
    402 
    403   reader = new MockUploadElementReader(kTestDataSize, false);
    404   reader->SetAsyncInitExpectation(OK);
    405   element_readers_.push_back(reader);
    406 
    407   reader = new MockUploadElementReader(kTestDataSize, true);
    408   EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK));
    409   element_readers_.push_back(reader);
    410 
    411   UploadDataStream stream(element_readers_.Pass(), 0);
    412 
    413   // Run Init().
    414   TestCompletionCallback callback;
    415   ASSERT_EQ(ERR_IO_PENDING, stream.Init(callback.callback()));
    416   EXPECT_EQ(OK, callback.WaitForResult());
    417 }
    418 
    419 // Init() of a reader fails asynchronously.
    420 TEST_F(UploadDataStreamTest, InitAsyncFailureAsync) {
    421   // Create UploadDataStream with a mock reader.
    422   MockUploadElementReader* reader = NULL;
    423 
    424   reader = new MockUploadElementReader(kTestDataSize, false);
    425   reader->SetAsyncInitExpectation(ERR_FAILED);
    426   element_readers_.push_back(reader);
    427 
    428   UploadDataStream stream(element_readers_.Pass(), 0);
    429 
    430   // Run Init().
    431   TestCompletionCallback callback;
    432   ASSERT_EQ(ERR_IO_PENDING, stream.Init(callback.callback()));
    433   EXPECT_EQ(ERR_FAILED, callback.WaitForResult());
    434 }
    435 
    436 // Init() of a reader fails synchronously.
    437 TEST_F(UploadDataStreamTest, InitAsyncFailureSync) {
    438   // Create UploadDataStream with mock readers.
    439   MockUploadElementReader* reader = NULL;
    440 
    441   reader = new MockUploadElementReader(kTestDataSize, false);
    442   reader->SetAsyncInitExpectation(OK);
    443   element_readers_.push_back(reader);
    444 
    445   reader = new MockUploadElementReader(kTestDataSize, true);
    446   EXPECT_CALL(*reader, Init(_)).WillOnce(Return(ERR_FAILED));
    447   element_readers_.push_back(reader);
    448 
    449   UploadDataStream stream(element_readers_.Pass(), 0);
    450 
    451   // Run Init().
    452   TestCompletionCallback callback;
    453   ASSERT_EQ(ERR_IO_PENDING, stream.Init(callback.callback()));
    454   EXPECT_EQ(ERR_FAILED, callback.WaitForResult());
    455 }
    456 
    457 // Read with a buffer whose size is same as the data.
    458 TEST_F(UploadDataStreamTest, ReadAsyncWithExactSizeBuffer) {
    459   element_readers_.push_back(new UploadBytesElementReader(
    460       kTestData, kTestDataSize));
    461   UploadDataStream stream(element_readers_.Pass(), 0);
    462 
    463   ASSERT_EQ(OK, stream.Init(CompletionCallback()));
    464   EXPECT_TRUE(stream.IsInMemory());
    465   EXPECT_EQ(kTestDataSize, stream.size());
    466   EXPECT_EQ(0U, stream.position());
    467   EXPECT_FALSE(stream.IsEOF());
    468   scoped_refptr<IOBuffer> buf = new IOBuffer(kTestDataSize);
    469   int bytes_read = stream.Read(buf.get(), kTestDataSize, CompletionCallback());
    470   ASSERT_EQ(static_cast<int>(kTestDataSize), bytes_read);  // Not an error.
    471   EXPECT_EQ(kTestDataSize, stream.position());
    472   ASSERT_TRUE(stream.IsEOF());
    473 }
    474 
    475 // Async Read() with on-memory and not-on-memory readers.
    476 TEST_F(UploadDataStreamTest, ReadAsync) {
    477   // Create UploadDataStream with mock readers.
    478   MockUploadElementReader* reader = NULL;
    479 
    480   reader = new MockUploadElementReader(kTestDataSize, true);
    481   EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK));
    482   reader->SetReadExpectation(kTestDataSize);
    483   element_readers_.push_back(reader);
    484 
    485   reader = new MockUploadElementReader(kTestDataSize, false);
    486   reader->SetAsyncInitExpectation(OK);
    487   reader->SetReadExpectation(kTestDataSize);
    488   element_readers_.push_back(reader);
    489 
    490   reader = new MockUploadElementReader(kTestDataSize, true);
    491   EXPECT_CALL(*reader, Init(_)).WillOnce(Return(OK));
    492   reader->SetReadExpectation(kTestDataSize);
    493   element_readers_.push_back(reader);
    494 
    495   reader = new MockUploadElementReader(kTestDataSize, false);
    496   reader->SetAsyncInitExpectation(OK);
    497   reader->SetReadExpectation(kTestDataSize);
    498   element_readers_.push_back(reader);
    499 
    500   UploadDataStream stream(element_readers_.Pass(), 0);
    501 
    502   // Run Init().
    503   TestCompletionCallback init_callback;
    504   EXPECT_EQ(ERR_IO_PENDING, stream.Init(init_callback.callback()));
    505   EXPECT_EQ(OK, init_callback.WaitForResult());
    506 
    507   scoped_refptr<IOBuffer> buf = new IOBuffer(kTestBufferSize);
    508 
    509   // Consume the first element.
    510   TestCompletionCallback read_callback1;
    511   EXPECT_EQ(static_cast<int>(kTestDataSize),
    512             stream.Read(buf.get(), kTestDataSize, read_callback1.callback()));
    513   base::MessageLoop::current()->RunUntilIdle();
    514   EXPECT_FALSE(read_callback1.have_result());
    515 
    516   // Consume the second element.
    517   TestCompletionCallback read_callback2;
    518   ASSERT_EQ(ERR_IO_PENDING,
    519             stream.Read(buf.get(), kTestDataSize, read_callback2.callback()));
    520   EXPECT_EQ(static_cast<int>(kTestDataSize), read_callback2.WaitForResult());
    521 
    522   // Consume the third and the fourth elements.
    523   TestCompletionCallback read_callback3;
    524   ASSERT_EQ(
    525       ERR_IO_PENDING,
    526       stream.Read(buf.get(), kTestDataSize * 2, read_callback3.callback()));
    527   EXPECT_EQ(static_cast<int>(kTestDataSize * 2),
    528             read_callback3.WaitForResult());
    529 }
    530 
    531 void UploadDataStreamTest::FileChangedHelper(const base::FilePath& file_path,
    532                                              const base::Time& time,
    533                                              bool error_expected) {
    534   // Don't use element_readers_ here, as this function is called twice, and
    535   // reusing element_readers_ is wrong.
    536   ScopedVector<UploadElementReader> element_readers;
    537   element_readers.push_back(new UploadFileElementReader(
    538       base::MessageLoopProxy::current().get(), file_path, 1, 2, time));
    539 
    540   TestCompletionCallback init_callback;
    541   UploadDataStream stream(element_readers.Pass(), 0);
    542   ASSERT_EQ(ERR_IO_PENDING, stream.Init(init_callback.callback()));
    543   int error_code = init_callback.WaitForResult();
    544   if (error_expected)
    545     ASSERT_EQ(ERR_UPLOAD_FILE_CHANGED, error_code);
    546   else
    547     ASSERT_EQ(OK, error_code);
    548 }
    549 
    550 TEST_F(UploadDataStreamTest, FileChanged) {
    551   base::FilePath temp_file_path;
    552   ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(),
    553                                              &temp_file_path));
    554   ASSERT_EQ(static_cast<int>(kTestDataSize),
    555             file_util::WriteFile(temp_file_path, kTestData, kTestDataSize));
    556 
    557   base::PlatformFileInfo file_info;
    558   ASSERT_TRUE(base::GetFileInfo(temp_file_path, &file_info));
    559 
    560   // Test file not changed.
    561   FileChangedHelper(temp_file_path, file_info.last_modified, false);
    562 
    563   // Test file changed.
    564   FileChangedHelper(temp_file_path,
    565                     file_info.last_modified - base::TimeDelta::FromSeconds(1),
    566                     true);
    567 }
    568 
    569 TEST_F(UploadDataStreamTest, MultipleInit) {
    570   base::FilePath temp_file_path;
    571   ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(),
    572                                              &temp_file_path));
    573   ASSERT_EQ(static_cast<int>(kTestDataSize),
    574             file_util::WriteFile(temp_file_path, kTestData, kTestDataSize));
    575 
    576   // Prepare data.
    577   element_readers_.push_back(new UploadBytesElementReader(
    578       kTestData, kTestDataSize));
    579   element_readers_.push_back(
    580       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
    581                                   temp_file_path,
    582                                   0,
    583                                   kuint64max,
    584                                   base::Time()));
    585   UploadDataStream stream(element_readers_.Pass(), 0);
    586 
    587   std::string expected_data(kTestData, kTestData + kTestDataSize);
    588   expected_data += expected_data;
    589 
    590   // Call Init().
    591   TestCompletionCallback init_callback1;
    592   ASSERT_EQ(ERR_IO_PENDING, stream.Init(init_callback1.callback()));
    593   ASSERT_EQ(OK, init_callback1.WaitForResult());
    594   EXPECT_FALSE(stream.IsEOF());
    595   EXPECT_EQ(kTestDataSize*2, stream.size());
    596 
    597   // Read.
    598   EXPECT_EQ(expected_data, ReadFromUploadDataStream(&stream));
    599   EXPECT_TRUE(stream.IsEOF());
    600 
    601   // Call Init() again to reset.
    602   TestCompletionCallback init_callback2;
    603   ASSERT_EQ(ERR_IO_PENDING, stream.Init(init_callback2.callback()));
    604   ASSERT_EQ(OK, init_callback2.WaitForResult());
    605   EXPECT_FALSE(stream.IsEOF());
    606   EXPECT_EQ(kTestDataSize*2, stream.size());
    607 
    608   // Read again.
    609   EXPECT_EQ(expected_data, ReadFromUploadDataStream(&stream));
    610   EXPECT_TRUE(stream.IsEOF());
    611 }
    612 
    613 TEST_F(UploadDataStreamTest, MultipleInitAsync) {
    614   base::FilePath temp_file_path;
    615   ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(),
    616                                              &temp_file_path));
    617   ASSERT_EQ(static_cast<int>(kTestDataSize),
    618             file_util::WriteFile(temp_file_path, kTestData, kTestDataSize));
    619   TestCompletionCallback test_callback;
    620 
    621   // Prepare data.
    622   element_readers_.push_back(new UploadBytesElementReader(
    623       kTestData, kTestDataSize));
    624   element_readers_.push_back(
    625       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
    626                                   temp_file_path,
    627                                   0,
    628                                   kuint64max,
    629                                   base::Time()));
    630   UploadDataStream stream(element_readers_.Pass(), 0);
    631 
    632   std::string expected_data(kTestData, kTestData + kTestDataSize);
    633   expected_data += expected_data;
    634 
    635   // Call Init().
    636   ASSERT_EQ(ERR_IO_PENDING, stream.Init(test_callback.callback()));
    637   EXPECT_EQ(OK, test_callback.WaitForResult());
    638   EXPECT_FALSE(stream.IsEOF());
    639   EXPECT_EQ(kTestDataSize*2, stream.size());
    640 
    641   // Read.
    642   EXPECT_EQ(expected_data, ReadFromUploadDataStream(&stream));
    643   EXPECT_TRUE(stream.IsEOF());
    644 
    645   // Call Init() again to reset.
    646   ASSERT_EQ(ERR_IO_PENDING, stream.Init(test_callback.callback()));
    647   EXPECT_EQ(OK, test_callback.WaitForResult());
    648   EXPECT_FALSE(stream.IsEOF());
    649   EXPECT_EQ(kTestDataSize*2, stream.size());
    650 
    651   // Read again.
    652   EXPECT_EQ(expected_data, ReadFromUploadDataStream(&stream));
    653   EXPECT_TRUE(stream.IsEOF());
    654 }
    655 
    656 TEST_F(UploadDataStreamTest, InitToReset) {
    657   base::FilePath temp_file_path;
    658   ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(),
    659                                              &temp_file_path));
    660   ASSERT_EQ(static_cast<int>(kTestDataSize),
    661             file_util::WriteFile(temp_file_path, kTestData, kTestDataSize));
    662 
    663   // Prepare data.
    664   element_readers_.push_back(new UploadBytesElementReader(
    665       kTestData, kTestDataSize));
    666   element_readers_.push_back(
    667       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
    668                                   temp_file_path,
    669                                   0,
    670                                   kuint64max,
    671                                   base::Time()));
    672   UploadDataStream stream(element_readers_.Pass(), 0);
    673 
    674   std::vector<char> expected_data(kTestData, kTestData + kTestDataSize);
    675   expected_data.insert(expected_data.end(), expected_data.begin(),
    676                        expected_data.begin() + kTestDataSize);
    677 
    678   // Call Init().
    679   TestCompletionCallback init_callback1;
    680   ASSERT_EQ(ERR_IO_PENDING, stream.Init(init_callback1.callback()));
    681   EXPECT_EQ(OK, init_callback1.WaitForResult());
    682   EXPECT_FALSE(stream.IsEOF());
    683   EXPECT_EQ(kTestDataSize*2, stream.size());
    684 
    685   // Read some.
    686   TestCompletionCallback read_callback1;
    687   std::vector<char> buf(kTestDataSize + kTestDataSize/2);
    688   scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]);
    689   EXPECT_EQ(
    690       ERR_IO_PENDING,
    691       stream.Read(wrapped_buffer.get(), buf.size(), read_callback1.callback()));
    692   EXPECT_EQ(static_cast<int>(buf.size()), read_callback1.WaitForResult());
    693   EXPECT_EQ(buf.size(), stream.position());
    694 
    695   // Call Init to reset the state.
    696   TestCompletionCallback init_callback2;
    697   ASSERT_EQ(ERR_IO_PENDING, stream.Init(init_callback2.callback()));
    698   EXPECT_EQ(OK, init_callback2.WaitForResult());
    699   EXPECT_FALSE(stream.IsEOF());
    700   EXPECT_EQ(kTestDataSize*2, stream.size());
    701 
    702   // Read.
    703   TestCompletionCallback read_callback2;
    704   std::vector<char> buf2(kTestDataSize*2);
    705   scoped_refptr<IOBuffer> wrapped_buffer2 = new WrappedIOBuffer(&buf2[0]);
    706   EXPECT_EQ(ERR_IO_PENDING,
    707             stream.Read(
    708                 wrapped_buffer2.get(), buf2.size(), read_callback2.callback()));
    709   EXPECT_EQ(static_cast<int>(buf2.size()), read_callback2.WaitForResult());
    710   EXPECT_EQ(expected_data, buf2);
    711 }
    712 
    713 TEST_F(UploadDataStreamTest, InitDuringAsyncInit) {
    714   base::FilePath temp_file_path;
    715   ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(),
    716                                              &temp_file_path));
    717   ASSERT_EQ(static_cast<int>(kTestDataSize),
    718             file_util::WriteFile(temp_file_path, kTestData, kTestDataSize));
    719 
    720   // Prepare data.
    721   element_readers_.push_back(new UploadBytesElementReader(
    722       kTestData, kTestDataSize));
    723   element_readers_.push_back(
    724       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
    725                                   temp_file_path,
    726                                   0,
    727                                   kuint64max,
    728                                   base::Time()));
    729   UploadDataStream stream(element_readers_.Pass(), 0);
    730 
    731   std::vector<char> expected_data(kTestData, kTestData + kTestDataSize);
    732   expected_data.insert(expected_data.end(), expected_data.begin(),
    733                        expected_data.begin() + kTestDataSize);
    734 
    735   // Start Init.
    736   TestCompletionCallback init_callback1;
    737   EXPECT_EQ(ERR_IO_PENDING, stream.Init(init_callback1.callback()));
    738 
    739   // Call Init again to cancel the previous init.
    740   TestCompletionCallback init_callback2;
    741   EXPECT_EQ(ERR_IO_PENDING, stream.Init(init_callback2.callback()));
    742   EXPECT_EQ(OK, init_callback2.WaitForResult());
    743   EXPECT_FALSE(stream.IsEOF());
    744   EXPECT_EQ(kTestDataSize*2, stream.size());
    745 
    746   // Read.
    747   TestCompletionCallback read_callback2;
    748   std::vector<char> buf2(kTestDataSize*2);
    749   scoped_refptr<IOBuffer> wrapped_buffer2 = new WrappedIOBuffer(&buf2[0]);
    750   EXPECT_EQ(ERR_IO_PENDING,
    751             stream.Read(
    752                 wrapped_buffer2.get(), buf2.size(), read_callback2.callback()));
    753   EXPECT_EQ(static_cast<int>(buf2.size()), read_callback2.WaitForResult());
    754   EXPECT_EQ(expected_data, buf2);
    755   EXPECT_TRUE(stream.IsEOF());
    756 
    757   // Make sure callbacks are not called for cancelled operations.
    758   EXPECT_FALSE(init_callback1.have_result());
    759 }
    760 
    761 TEST_F(UploadDataStreamTest, InitDuringAsyncRead) {
    762   base::FilePath temp_file_path;
    763   ASSERT_TRUE(base::CreateTemporaryFileInDir(temp_dir_.path(),
    764                                              &temp_file_path));
    765   ASSERT_EQ(static_cast<int>(kTestDataSize),
    766             file_util::WriteFile(temp_file_path, kTestData, kTestDataSize));
    767 
    768   // Prepare data.
    769   element_readers_.push_back(new UploadBytesElementReader(
    770       kTestData, kTestDataSize));
    771   element_readers_.push_back(
    772       new UploadFileElementReader(base::MessageLoopProxy::current().get(),
    773                                   temp_file_path,
    774                                   0,
    775                                   kuint64max,
    776                                   base::Time()));
    777   UploadDataStream stream(element_readers_.Pass(), 0);
    778 
    779   std::vector<char> expected_data(kTestData, kTestData + kTestDataSize);
    780   expected_data.insert(expected_data.end(), expected_data.begin(),
    781                        expected_data.begin() + kTestDataSize);
    782 
    783   // Call Init().
    784   TestCompletionCallback init_callback1;
    785   ASSERT_EQ(ERR_IO_PENDING, stream.Init(init_callback1.callback()));
    786   EXPECT_EQ(OK, init_callback1.WaitForResult());
    787   EXPECT_FALSE(stream.IsEOF());
    788   EXPECT_EQ(kTestDataSize*2, stream.size());
    789 
    790   // Start reading.
    791   TestCompletionCallback read_callback1;
    792   std::vector<char> buf(kTestDataSize*2);
    793   scoped_refptr<IOBuffer> wrapped_buffer = new WrappedIOBuffer(&buf[0]);
    794   EXPECT_EQ(
    795       ERR_IO_PENDING,
    796       stream.Read(wrapped_buffer.get(), buf.size(), read_callback1.callback()));
    797 
    798   // Call Init to cancel the previous read.
    799   TestCompletionCallback init_callback2;
    800   EXPECT_EQ(ERR_IO_PENDING, stream.Init(init_callback2.callback()));
    801   EXPECT_EQ(OK, init_callback2.WaitForResult());
    802   EXPECT_FALSE(stream.IsEOF());
    803   EXPECT_EQ(kTestDataSize*2, stream.size());
    804 
    805   // Read.
    806   TestCompletionCallback read_callback2;
    807   std::vector<char> buf2(kTestDataSize*2);
    808   scoped_refptr<IOBuffer> wrapped_buffer2 = new WrappedIOBuffer(&buf2[0]);
    809   EXPECT_EQ(ERR_IO_PENDING,
    810             stream.Read(
    811                 wrapped_buffer2.get(), buf2.size(), read_callback2.callback()));
    812   EXPECT_EQ(static_cast<int>(buf2.size()), read_callback2.WaitForResult());
    813   EXPECT_EQ(expected_data, buf2);
    814   EXPECT_TRUE(stream.IsEOF());
    815 
    816   // Make sure callbacks are not called for cancelled operations.
    817   EXPECT_FALSE(read_callback1.have_result());
    818 }
    819 
    820 }  // namespace net
    821