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