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