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
28using ::testing::DoAll;
29using ::testing::Invoke;
30using ::testing::Return;
31using ::testing::_;
32
33namespace net {
34
35namespace {
36
37const char kTestData[] = "0123456789";
38const size_t kTestDataSize = arraysize(kTestData) - 1;
39const size_t kTestBufferSize = 1 << 14;  // 16KB.
40
41// Reads data from the upload data stream, and returns the data as string.
42std::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.
57class 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
125class 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
144TEST_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
153TEST_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
172TEST_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
206TEST_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
250TEST_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
285TEST_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
324TEST_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
365TEST_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.
387TEST_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.
420TEST_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.
437TEST_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.
458TEST_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.
476TEST_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
531void 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
550TEST_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
569TEST_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
613TEST_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
656TEST_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
713TEST_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
761TEST_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