• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
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.
ReadFromUploadDataStream(UploadDataStream * stream)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:
MockUploadElementReader(int content_length,bool is_in_memory)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 
~MockUploadElementReader()66   virtual ~MockUploadElementReader() {}
67 
68   // UploadElementReader overrides.
69   MOCK_METHOD1(Init, int(const CompletionCallback& callback));
GetContentLength() const70   virtual uint64 GetContentLength() const OVERRIDE { return content_length_; }
BytesRemaining() const71   virtual uint64 BytesRemaining() const OVERRIDE { return bytes_remaining_; }
IsInMemory() const72   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.
SetAsyncInitExpectation(int result)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().
SetReadExpectation(int result)86   void SetReadExpectation(int result) {
87     read_result_ = result;
88     EXPECT_CALL(*this, Read(_, _, _))
89         .WillOnce(Invoke(this, &MockUploadElementReader::OnRead));
90   }
91 
92  private:
OnInit(const CompletionCallback & callback)93   void OnInit(const CompletionCallback& callback) {
94     base::MessageLoop::current()->PostTask(FROM_HERE,
95                                            base::Bind(callback, init_result_));
96   }
97 
OnRead(IOBuffer * buf,int buf_length,const CompletionCallback & callback)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:
SetUp()127   virtual void SetUp() {
128     PlatformTest::SetUp();
129     ASSERT_TRUE(temp_dir_.CreateUniqueTempDir());
130   }
~UploadDataStreamTest()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 
TEST_F(UploadDataStreamTest,EmptyUploadData)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 
TEST_F(UploadDataStreamTest,ConsumeAllBytes)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 
TEST_F(UploadDataStreamTest,File)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 
TEST_F(UploadDataStreamTest,FileSmallerThanLength)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 
TEST_F(UploadDataStreamTest,ReadErrorSync)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 
TEST_F(UploadDataStreamTest,ReadErrorAsync)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 
TEST_F(UploadDataStreamTest,FileAndBytes)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 
TEST_F(UploadDataStreamTest,Chunk)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.
TEST_F(UploadDataStreamTest,InitAsync)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.
TEST_F(UploadDataStreamTest,InitAsyncFailureAsync)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.
TEST_F(UploadDataStreamTest,InitAsyncFailureSync)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.
TEST_F(UploadDataStreamTest,ReadAsyncWithExactSizeBuffer)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.
TEST_F(UploadDataStreamTest,ReadAsync)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 
FileChangedHelper(const base::FilePath & file_path,const base::Time & time,bool error_expected)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 
TEST_F(UploadDataStreamTest,FileChanged)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 
TEST_F(UploadDataStreamTest,MultipleInit)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 
TEST_F(UploadDataStreamTest,MultipleInitAsync)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 
TEST_F(UploadDataStreamTest,InitToReset)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 
TEST_F(UploadDataStreamTest,InitDuringAsyncInit)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 
TEST_F(UploadDataStreamTest,InitDuringAsyncRead)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