xref: /aosp_15_r20/external/cronet/net/base/file_stream_unittest.cc (revision 6777b5387eb2ff775bb5750e3f5d96f37fb7352b)
1*6777b538SAndroid Build Coastguard Worker // Copyright 2012 The Chromium Authors
2*6777b538SAndroid Build Coastguard Worker // Use of this source code is governed by a BSD-style license that can be
3*6777b538SAndroid Build Coastguard Worker // found in the LICENSE file.
4*6777b538SAndroid Build Coastguard Worker 
5*6777b538SAndroid Build Coastguard Worker #include "net/base/file_stream.h"
6*6777b538SAndroid Build Coastguard Worker 
7*6777b538SAndroid Build Coastguard Worker #include <string>
8*6777b538SAndroid Build Coastguard Worker #include <utility>
9*6777b538SAndroid Build Coastguard Worker 
10*6777b538SAndroid Build Coastguard Worker #include "base/files/file.h"
11*6777b538SAndroid Build Coastguard Worker #include "base/files/file_util.h"
12*6777b538SAndroid Build Coastguard Worker #include "base/functional/bind.h"
13*6777b538SAndroid Build Coastguard Worker #include "base/functional/callback.h"
14*6777b538SAndroid Build Coastguard Worker #include "base/memory/raw_ptr.h"
15*6777b538SAndroid Build Coastguard Worker #include "base/path_service.h"
16*6777b538SAndroid Build Coastguard Worker #include "base/run_loop.h"
17*6777b538SAndroid Build Coastguard Worker #include "base/strings/string_util.h"
18*6777b538SAndroid Build Coastguard Worker #include "base/synchronization/waitable_event.h"
19*6777b538SAndroid Build Coastguard Worker #include "base/task/current_thread.h"
20*6777b538SAndroid Build Coastguard Worker #include "base/task/single_thread_task_runner.h"
21*6777b538SAndroid Build Coastguard Worker #include "base/test/test_timeouts.h"
22*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread.h"
23*6777b538SAndroid Build Coastguard Worker #include "base/threading/thread_restrictions.h"
24*6777b538SAndroid Build Coastguard Worker #include "build/build_config.h"
25*6777b538SAndroid Build Coastguard Worker #include "net/base/io_buffer.h"
26*6777b538SAndroid Build Coastguard Worker #include "net/base/net_errors.h"
27*6777b538SAndroid Build Coastguard Worker #include "net/base/test_completion_callback.h"
28*6777b538SAndroid Build Coastguard Worker #include "net/log/test_net_log.h"
29*6777b538SAndroid Build Coastguard Worker #include "net/test/gtest_util.h"
30*6777b538SAndroid Build Coastguard Worker #include "net/test/test_with_task_environment.h"
31*6777b538SAndroid Build Coastguard Worker #include "testing/gmock/include/gmock/gmock.h"
32*6777b538SAndroid Build Coastguard Worker #include "testing/gtest/include/gtest/gtest.h"
33*6777b538SAndroid Build Coastguard Worker #include "testing/platform_test.h"
34*6777b538SAndroid Build Coastguard Worker 
35*6777b538SAndroid Build Coastguard Worker using net::test::IsError;
36*6777b538SAndroid Build Coastguard Worker using net::test::IsOk;
37*6777b538SAndroid Build Coastguard Worker 
38*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID)
39*6777b538SAndroid Build Coastguard Worker #include "base/test/test_file_util.h"
40*6777b538SAndroid Build Coastguard Worker #endif
41*6777b538SAndroid Build Coastguard Worker 
42*6777b538SAndroid Build Coastguard Worker namespace net {
43*6777b538SAndroid Build Coastguard Worker 
44*6777b538SAndroid Build Coastguard Worker namespace {
45*6777b538SAndroid Build Coastguard Worker 
46*6777b538SAndroid Build Coastguard Worker constexpr char kTestData[] = "0123456789";
47*6777b538SAndroid Build Coastguard Worker constexpr int kTestDataSize = std::size(kTestData) - 1;
48*6777b538SAndroid Build Coastguard Worker 
49*6777b538SAndroid Build Coastguard Worker // Creates an IOBufferWithSize that contains the kTestDataSize.
CreateTestDataBuffer()50*6777b538SAndroid Build Coastguard Worker scoped_refptr<IOBufferWithSize> CreateTestDataBuffer() {
51*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBufferWithSize> buf =
52*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<IOBufferWithSize>(kTestDataSize);
53*6777b538SAndroid Build Coastguard Worker   memcpy(buf->data(), kTestData, kTestDataSize);
54*6777b538SAndroid Build Coastguard Worker   return buf;
55*6777b538SAndroid Build Coastguard Worker }
56*6777b538SAndroid Build Coastguard Worker 
57*6777b538SAndroid Build Coastguard Worker }  // namespace
58*6777b538SAndroid Build Coastguard Worker 
59*6777b538SAndroid Build Coastguard Worker class FileStreamTest : public PlatformTest, public WithTaskEnvironment {
60*6777b538SAndroid Build Coastguard Worker  public:
SetUp()61*6777b538SAndroid Build Coastguard Worker   void SetUp() override {
62*6777b538SAndroid Build Coastguard Worker     PlatformTest::SetUp();
63*6777b538SAndroid Build Coastguard Worker 
64*6777b538SAndroid Build Coastguard Worker     base::CreateTemporaryFile(&temp_file_path_);
65*6777b538SAndroid Build Coastguard Worker     base::WriteFile(temp_file_path_, kTestData);
66*6777b538SAndroid Build Coastguard Worker   }
TearDown()67*6777b538SAndroid Build Coastguard Worker   void TearDown() override {
68*6777b538SAndroid Build Coastguard Worker     // FileStreamContexts must be asynchronously closed on the file task runner
69*6777b538SAndroid Build Coastguard Worker     // before they can be deleted. Pump the RunLoop to avoid leaks.
70*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
71*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(base::DeleteFile(temp_file_path_));
72*6777b538SAndroid Build Coastguard Worker 
73*6777b538SAndroid Build Coastguard Worker     PlatformTest::TearDown();
74*6777b538SAndroid Build Coastguard Worker   }
75*6777b538SAndroid Build Coastguard Worker 
temp_file_path() const76*6777b538SAndroid Build Coastguard Worker   const base::FilePath temp_file_path() const { return temp_file_path_; }
77*6777b538SAndroid Build Coastguard Worker 
78*6777b538SAndroid Build Coastguard Worker  private:
79*6777b538SAndroid Build Coastguard Worker   base::FilePath temp_file_path_;
80*6777b538SAndroid Build Coastguard Worker };
81*6777b538SAndroid Build Coastguard Worker 
82*6777b538SAndroid Build Coastguard Worker namespace {
83*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileStreamTest,OpenExplicitClose)84*6777b538SAndroid Build Coastguard Worker TEST_F(FileStreamTest, OpenExplicitClose) {
85*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
86*6777b538SAndroid Build Coastguard Worker   FileStream stream(base::SingleThreadTaskRunner::GetCurrentDefault());
87*6777b538SAndroid Build Coastguard Worker   int flags = base::File::FLAG_OPEN |
88*6777b538SAndroid Build Coastguard Worker               base::File::FLAG_READ |
89*6777b538SAndroid Build Coastguard Worker               base::File::FLAG_ASYNC;
90*6777b538SAndroid Build Coastguard Worker   int rv = stream.Open(temp_file_path(), flags, callback.callback());
91*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
92*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(callback.WaitForResult(), IsOk());
93*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(stream.IsOpen());
94*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(stream.Close(callback.callback()), IsError(ERR_IO_PENDING));
95*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(callback.WaitForResult(), IsOk());
96*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(stream.IsOpen());
97*6777b538SAndroid Build Coastguard Worker }
98*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileStreamTest,OpenExplicitCloseOrphaned)99*6777b538SAndroid Build Coastguard Worker TEST_F(FileStreamTest, OpenExplicitCloseOrphaned) {
100*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
101*6777b538SAndroid Build Coastguard Worker   auto stream = std::make_unique<FileStream>(
102*6777b538SAndroid Build Coastguard Worker       base::SingleThreadTaskRunner::GetCurrentDefault());
103*6777b538SAndroid Build Coastguard Worker   int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
104*6777b538SAndroid Build Coastguard Worker               base::File::FLAG_ASYNC;
105*6777b538SAndroid Build Coastguard Worker   int rv = stream->Open(temp_file_path(), flags, callback.callback());
106*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
107*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(callback.WaitForResult(), IsOk());
108*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(stream->IsOpen());
109*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(stream->Close(callback.callback()), IsError(ERR_IO_PENDING));
110*6777b538SAndroid Build Coastguard Worker   stream.reset();
111*6777b538SAndroid Build Coastguard Worker   // File isn't actually closed yet.
112*6777b538SAndroid Build Coastguard Worker   base::RunLoop runloop;
113*6777b538SAndroid Build Coastguard Worker   runloop.RunUntilIdle();
114*6777b538SAndroid Build Coastguard Worker   // The file should now be closed, though the callback has not been called.
115*6777b538SAndroid Build Coastguard Worker }
116*6777b538SAndroid Build Coastguard Worker 
117*6777b538SAndroid Build Coastguard Worker // Test the use of FileStream with a file handle provided at construction.
TEST_F(FileStreamTest,UseFileHandle)118*6777b538SAndroid Build Coastguard Worker TEST_F(FileStreamTest, UseFileHandle) {
119*6777b538SAndroid Build Coastguard Worker   int rv = 0;
120*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
121*6777b538SAndroid Build Coastguard Worker   TestInt64CompletionCallback callback64;
122*6777b538SAndroid Build Coastguard Worker   // 1. Test reading with a file handle.
123*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(base::WriteFile(temp_file_path(), kTestData));
124*6777b538SAndroid Build Coastguard Worker   int flags = base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ |
125*6777b538SAndroid Build Coastguard Worker               base::File::FLAG_ASYNC;
126*6777b538SAndroid Build Coastguard Worker   base::File file1(temp_file_path(), flags);
127*6777b538SAndroid Build Coastguard Worker 
128*6777b538SAndroid Build Coastguard Worker   // Seek to the beginning of the file and read.
129*6777b538SAndroid Build Coastguard Worker   auto read_stream = std::make_unique<FileStream>(
130*6777b538SAndroid Build Coastguard Worker       std::move(file1), base::SingleThreadTaskRunner::GetCurrentDefault());
131*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(read_stream->Seek(0, callback64.callback()),
132*6777b538SAndroid Build Coastguard Worker               IsError(ERR_IO_PENDING));
133*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0, callback64.WaitForResult());
134*6777b538SAndroid Build Coastguard Worker   // Read into buffer and compare.
135*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBufferWithSize> read_buffer =
136*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<IOBufferWithSize>(kTestDataSize);
137*6777b538SAndroid Build Coastguard Worker   rv = read_stream->Read(read_buffer.get(), kTestDataSize, callback.callback());
138*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(kTestDataSize, callback.GetResult(rv));
139*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0, memcmp(kTestData, read_buffer->data(), kTestDataSize));
140*6777b538SAndroid Build Coastguard Worker   read_stream.reset();
141*6777b538SAndroid Build Coastguard Worker 
142*6777b538SAndroid Build Coastguard Worker   // 2. Test writing with a file handle.
143*6777b538SAndroid Build Coastguard Worker   base::DeleteFile(temp_file_path());
144*6777b538SAndroid Build Coastguard Worker   flags = base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE |
145*6777b538SAndroid Build Coastguard Worker           base::File::FLAG_ASYNC;
146*6777b538SAndroid Build Coastguard Worker   base::File file2(temp_file_path(), flags);
147*6777b538SAndroid Build Coastguard Worker 
148*6777b538SAndroid Build Coastguard Worker   auto write_stream = std::make_unique<FileStream>(
149*6777b538SAndroid Build Coastguard Worker       std::move(file2), base::SingleThreadTaskRunner::GetCurrentDefault());
150*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(write_stream->Seek(0, callback64.callback()),
151*6777b538SAndroid Build Coastguard Worker               IsError(ERR_IO_PENDING));
152*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0, callback64.WaitForResult());
153*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBufferWithSize> write_buffer = CreateTestDataBuffer();
154*6777b538SAndroid Build Coastguard Worker   rv = write_stream->Write(write_buffer.get(), kTestDataSize,
155*6777b538SAndroid Build Coastguard Worker                            callback.callback());
156*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(kTestDataSize, callback.GetResult(rv));
157*6777b538SAndroid Build Coastguard Worker   write_stream.reset();
158*6777b538SAndroid Build Coastguard Worker 
159*6777b538SAndroid Build Coastguard Worker   // Read into buffer and compare to make sure the handle worked fine.
160*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(kTestDataSize,
161*6777b538SAndroid Build Coastguard Worker             base::ReadFile(temp_file_path(), read_buffer->data(),
162*6777b538SAndroid Build Coastguard Worker                            kTestDataSize));
163*6777b538SAndroid Build Coastguard Worker   ASSERT_EQ(0, memcmp(kTestData, read_buffer->data(), kTestDataSize));
164*6777b538SAndroid Build Coastguard Worker }
165*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileStreamTest,UseClosedStream)166*6777b538SAndroid Build Coastguard Worker TEST_F(FileStreamTest, UseClosedStream) {
167*6777b538SAndroid Build Coastguard Worker   int rv = 0;
168*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
169*6777b538SAndroid Build Coastguard Worker   TestInt64CompletionCallback callback64;
170*6777b538SAndroid Build Coastguard Worker 
171*6777b538SAndroid Build Coastguard Worker   FileStream stream(base::SingleThreadTaskRunner::GetCurrentDefault());
172*6777b538SAndroid Build Coastguard Worker 
173*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(stream.IsOpen());
174*6777b538SAndroid Build Coastguard Worker 
175*6777b538SAndroid Build Coastguard Worker   // Try seeking...
176*6777b538SAndroid Build Coastguard Worker   rv = stream.Seek(5, callback64.callback());
177*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(callback64.GetResult(rv), IsError(ERR_UNEXPECTED));
178*6777b538SAndroid Build Coastguard Worker 
179*6777b538SAndroid Build Coastguard Worker   // Try reading...
180*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBufferWithSize> buf =
181*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<IOBufferWithSize>(10);
182*6777b538SAndroid Build Coastguard Worker   rv = stream.Read(buf.get(), buf->size(), callback.callback());
183*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(callback.GetResult(rv), IsError(ERR_UNEXPECTED));
184*6777b538SAndroid Build Coastguard Worker }
185*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileStreamTest,Read)186*6777b538SAndroid Build Coastguard Worker TEST_F(FileStreamTest, Read) {
187*6777b538SAndroid Build Coastguard Worker   int64_t file_size;
188*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
189*6777b538SAndroid Build Coastguard Worker 
190*6777b538SAndroid Build Coastguard Worker   FileStream stream(base::SingleThreadTaskRunner::GetCurrentDefault());
191*6777b538SAndroid Build Coastguard Worker   int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
192*6777b538SAndroid Build Coastguard Worker               base::File::FLAG_ASYNC;
193*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
194*6777b538SAndroid Build Coastguard Worker   int rv = stream.Open(temp_file_path(), flags, callback.callback());
195*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(callback.GetResult(rv), IsOk());
196*6777b538SAndroid Build Coastguard Worker 
197*6777b538SAndroid Build Coastguard Worker   int total_bytes_read = 0;
198*6777b538SAndroid Build Coastguard Worker 
199*6777b538SAndroid Build Coastguard Worker   std::string data_read;
200*6777b538SAndroid Build Coastguard Worker   for (;;) {
201*6777b538SAndroid Build Coastguard Worker     scoped_refptr<IOBufferWithSize> buf =
202*6777b538SAndroid Build Coastguard Worker         base::MakeRefCounted<IOBufferWithSize>(4);
203*6777b538SAndroid Build Coastguard Worker     rv = stream.Read(buf.get(), buf->size(), callback.callback());
204*6777b538SAndroid Build Coastguard Worker     rv = callback.GetResult(rv);
205*6777b538SAndroid Build Coastguard Worker     EXPECT_LE(0, rv);
206*6777b538SAndroid Build Coastguard Worker     if (rv <= 0)
207*6777b538SAndroid Build Coastguard Worker       break;
208*6777b538SAndroid Build Coastguard Worker     total_bytes_read += rv;
209*6777b538SAndroid Build Coastguard Worker     data_read.append(buf->data(), rv);
210*6777b538SAndroid Build Coastguard Worker   }
211*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(file_size, total_bytes_read);
212*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kTestData, data_read);
213*6777b538SAndroid Build Coastguard Worker }
214*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileStreamTest,Read_EarlyDelete)215*6777b538SAndroid Build Coastguard Worker TEST_F(FileStreamTest, Read_EarlyDelete) {
216*6777b538SAndroid Build Coastguard Worker   int64_t file_size;
217*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
218*6777b538SAndroid Build Coastguard Worker 
219*6777b538SAndroid Build Coastguard Worker   auto stream = std::make_unique<FileStream>(
220*6777b538SAndroid Build Coastguard Worker       base::SingleThreadTaskRunner::GetCurrentDefault());
221*6777b538SAndroid Build Coastguard Worker   int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
222*6777b538SAndroid Build Coastguard Worker               base::File::FLAG_ASYNC;
223*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
224*6777b538SAndroid Build Coastguard Worker   int rv = stream->Open(temp_file_path(), flags, callback.callback());
225*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
226*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(callback.WaitForResult(), IsOk());
227*6777b538SAndroid Build Coastguard Worker 
228*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBufferWithSize> buf =
229*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<IOBufferWithSize>(4);
230*6777b538SAndroid Build Coastguard Worker   rv = stream->Read(buf.get(), buf->size(), callback.callback());
231*6777b538SAndroid Build Coastguard Worker   stream.reset();  // Delete instead of closing it.
232*6777b538SAndroid Build Coastguard Worker   if (rv < 0) {
233*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
234*6777b538SAndroid Build Coastguard Worker     // The callback should not be called if the request is cancelled.
235*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
236*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(callback.have_result());
237*6777b538SAndroid Build Coastguard Worker   } else {
238*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(std::string(kTestData, rv), std::string(buf->data(), rv));
239*6777b538SAndroid Build Coastguard Worker   }
240*6777b538SAndroid Build Coastguard Worker }
241*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileStreamTest,Read_FromOffset)242*6777b538SAndroid Build Coastguard Worker TEST_F(FileStreamTest, Read_FromOffset) {
243*6777b538SAndroid Build Coastguard Worker   int64_t file_size;
244*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
245*6777b538SAndroid Build Coastguard Worker 
246*6777b538SAndroid Build Coastguard Worker   FileStream stream(base::SingleThreadTaskRunner::GetCurrentDefault());
247*6777b538SAndroid Build Coastguard Worker   int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
248*6777b538SAndroid Build Coastguard Worker               base::File::FLAG_ASYNC;
249*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
250*6777b538SAndroid Build Coastguard Worker   int rv = stream.Open(temp_file_path(), flags, callback.callback());
251*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
252*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(callback.WaitForResult(), IsOk());
253*6777b538SAndroid Build Coastguard Worker 
254*6777b538SAndroid Build Coastguard Worker   TestInt64CompletionCallback callback64;
255*6777b538SAndroid Build Coastguard Worker   const int64_t kOffset = 3;
256*6777b538SAndroid Build Coastguard Worker   rv = stream.Seek(kOffset, callback64.callback());
257*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
258*6777b538SAndroid Build Coastguard Worker   int64_t new_offset = callback64.WaitForResult();
259*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kOffset, new_offset);
260*6777b538SAndroid Build Coastguard Worker 
261*6777b538SAndroid Build Coastguard Worker   int total_bytes_read = 0;
262*6777b538SAndroid Build Coastguard Worker 
263*6777b538SAndroid Build Coastguard Worker   std::string data_read;
264*6777b538SAndroid Build Coastguard Worker   for (;;) {
265*6777b538SAndroid Build Coastguard Worker     scoped_refptr<IOBufferWithSize> buf =
266*6777b538SAndroid Build Coastguard Worker         base::MakeRefCounted<IOBufferWithSize>(4);
267*6777b538SAndroid Build Coastguard Worker     rv = stream.Read(buf.get(), buf->size(), callback.callback());
268*6777b538SAndroid Build Coastguard Worker     if (rv == ERR_IO_PENDING)
269*6777b538SAndroid Build Coastguard Worker       rv = callback.WaitForResult();
270*6777b538SAndroid Build Coastguard Worker     EXPECT_LE(0, rv);
271*6777b538SAndroid Build Coastguard Worker     if (rv <= 0)
272*6777b538SAndroid Build Coastguard Worker       break;
273*6777b538SAndroid Build Coastguard Worker     total_bytes_read += rv;
274*6777b538SAndroid Build Coastguard Worker     data_read.append(buf->data(), rv);
275*6777b538SAndroid Build Coastguard Worker   }
276*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(file_size - kOffset, total_bytes_read);
277*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kTestData + kOffset, data_read);
278*6777b538SAndroid Build Coastguard Worker }
279*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileStreamTest,Write)280*6777b538SAndroid Build Coastguard Worker TEST_F(FileStreamTest, Write) {
281*6777b538SAndroid Build Coastguard Worker   FileStream stream(base::SingleThreadTaskRunner::GetCurrentDefault());
282*6777b538SAndroid Build Coastguard Worker   int flags = base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
283*6777b538SAndroid Build Coastguard Worker               base::File::FLAG_ASYNC;
284*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
285*6777b538SAndroid Build Coastguard Worker   int rv = stream.Open(temp_file_path(), flags, callback.callback());
286*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(callback.GetResult(rv), IsOk());
287*6777b538SAndroid Build Coastguard Worker 
288*6777b538SAndroid Build Coastguard Worker   int64_t file_size;
289*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
290*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, file_size);
291*6777b538SAndroid Build Coastguard Worker 
292*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBuffer> buf = CreateTestDataBuffer();
293*6777b538SAndroid Build Coastguard Worker   rv = stream.Write(buf.get(), kTestDataSize, callback.callback());
294*6777b538SAndroid Build Coastguard Worker   rv = callback.GetResult(rv);
295*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kTestDataSize, rv);
296*6777b538SAndroid Build Coastguard Worker 
297*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
298*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kTestDataSize, file_size);
299*6777b538SAndroid Build Coastguard Worker 
300*6777b538SAndroid Build Coastguard Worker   std::string data_read;
301*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::ReadFileToString(temp_file_path(), &data_read));
302*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kTestData, data_read);
303*6777b538SAndroid Build Coastguard Worker }
304*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileStreamTest,Write_EarlyDelete)305*6777b538SAndroid Build Coastguard Worker TEST_F(FileStreamTest, Write_EarlyDelete) {
306*6777b538SAndroid Build Coastguard Worker   auto stream = std::make_unique<FileStream>(
307*6777b538SAndroid Build Coastguard Worker       base::SingleThreadTaskRunner::GetCurrentDefault());
308*6777b538SAndroid Build Coastguard Worker   int flags = base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
309*6777b538SAndroid Build Coastguard Worker               base::File::FLAG_ASYNC;
310*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
311*6777b538SAndroid Build Coastguard Worker   int rv = stream->Open(temp_file_path(), flags, callback.callback());
312*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
313*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(callback.WaitForResult(), IsOk());
314*6777b538SAndroid Build Coastguard Worker 
315*6777b538SAndroid Build Coastguard Worker   int64_t file_size;
316*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
317*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, file_size);
318*6777b538SAndroid Build Coastguard Worker 
319*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
320*6777b538SAndroid Build Coastguard Worker   rv = stream->Write(buf.get(), buf->size(), callback.callback());
321*6777b538SAndroid Build Coastguard Worker   stream.reset();
322*6777b538SAndroid Build Coastguard Worker   if (rv < 0) {
323*6777b538SAndroid Build Coastguard Worker     EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
324*6777b538SAndroid Build Coastguard Worker     // The callback should not be called if the request is cancelled.
325*6777b538SAndroid Build Coastguard Worker     base::RunLoop().RunUntilIdle();
326*6777b538SAndroid Build Coastguard Worker     EXPECT_FALSE(callback.have_result());
327*6777b538SAndroid Build Coastguard Worker   } else {
328*6777b538SAndroid Build Coastguard Worker     EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
329*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(file_size, rv);
330*6777b538SAndroid Build Coastguard Worker   }
331*6777b538SAndroid Build Coastguard Worker }
332*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileStreamTest,Write_FromOffset)333*6777b538SAndroid Build Coastguard Worker TEST_F(FileStreamTest, Write_FromOffset) {
334*6777b538SAndroid Build Coastguard Worker   int64_t file_size;
335*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
336*6777b538SAndroid Build Coastguard Worker 
337*6777b538SAndroid Build Coastguard Worker   FileStream stream(base::SingleThreadTaskRunner::GetCurrentDefault());
338*6777b538SAndroid Build Coastguard Worker   int flags = base::File::FLAG_OPEN | base::File::FLAG_WRITE |
339*6777b538SAndroid Build Coastguard Worker               base::File::FLAG_ASYNC;
340*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
341*6777b538SAndroid Build Coastguard Worker   int rv = stream.Open(temp_file_path(), flags, callback.callback());
342*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
343*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(callback.WaitForResult(), IsOk());
344*6777b538SAndroid Build Coastguard Worker 
345*6777b538SAndroid Build Coastguard Worker   TestInt64CompletionCallback callback64;
346*6777b538SAndroid Build Coastguard Worker   const int64_t kOffset = kTestDataSize;
347*6777b538SAndroid Build Coastguard Worker   rv = stream.Seek(kOffset, callback64.callback());
348*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
349*6777b538SAndroid Build Coastguard Worker   int64_t new_offset = callback64.WaitForResult();
350*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kTestDataSize, new_offset);
351*6777b538SAndroid Build Coastguard Worker 
352*6777b538SAndroid Build Coastguard Worker   int total_bytes_written = 0;
353*6777b538SAndroid Build Coastguard Worker 
354*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBufferWithSize> buffer = CreateTestDataBuffer();
355*6777b538SAndroid Build Coastguard Worker   int buffer_size = buffer->size();
356*6777b538SAndroid Build Coastguard Worker   scoped_refptr<DrainableIOBuffer> drainable =
357*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<DrainableIOBuffer>(std::move(buffer), buffer_size);
358*6777b538SAndroid Build Coastguard Worker   while (total_bytes_written != kTestDataSize) {
359*6777b538SAndroid Build Coastguard Worker     rv = stream.Write(drainable.get(), drainable->BytesRemaining(),
360*6777b538SAndroid Build Coastguard Worker                       callback.callback());
361*6777b538SAndroid Build Coastguard Worker     if (rv == ERR_IO_PENDING)
362*6777b538SAndroid Build Coastguard Worker       rv = callback.WaitForResult();
363*6777b538SAndroid Build Coastguard Worker     EXPECT_LT(0, rv);
364*6777b538SAndroid Build Coastguard Worker     if (rv <= 0)
365*6777b538SAndroid Build Coastguard Worker       break;
366*6777b538SAndroid Build Coastguard Worker     drainable->DidConsume(rv);
367*6777b538SAndroid Build Coastguard Worker     total_bytes_written += rv;
368*6777b538SAndroid Build Coastguard Worker   }
369*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
370*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(file_size, kTestDataSize * 2);
371*6777b538SAndroid Build Coastguard Worker }
372*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileStreamTest,BasicReadWrite)373*6777b538SAndroid Build Coastguard Worker TEST_F(FileStreamTest, BasicReadWrite) {
374*6777b538SAndroid Build Coastguard Worker   int64_t file_size;
375*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
376*6777b538SAndroid Build Coastguard Worker 
377*6777b538SAndroid Build Coastguard Worker   auto stream = std::make_unique<FileStream>(
378*6777b538SAndroid Build Coastguard Worker       base::SingleThreadTaskRunner::GetCurrentDefault());
379*6777b538SAndroid Build Coastguard Worker   int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
380*6777b538SAndroid Build Coastguard Worker               base::File::FLAG_WRITE | base::File::FLAG_ASYNC;
381*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
382*6777b538SAndroid Build Coastguard Worker   int rv = stream->Open(temp_file_path(), flags, callback.callback());
383*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
384*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(callback.WaitForResult(), IsOk());
385*6777b538SAndroid Build Coastguard Worker 
386*6777b538SAndroid Build Coastguard Worker   int64_t total_bytes_read = 0;
387*6777b538SAndroid Build Coastguard Worker 
388*6777b538SAndroid Build Coastguard Worker   std::string data_read;
389*6777b538SAndroid Build Coastguard Worker   for (;;) {
390*6777b538SAndroid Build Coastguard Worker     scoped_refptr<IOBufferWithSize> buf =
391*6777b538SAndroid Build Coastguard Worker         base::MakeRefCounted<IOBufferWithSize>(4);
392*6777b538SAndroid Build Coastguard Worker     rv = stream->Read(buf.get(), buf->size(), callback.callback());
393*6777b538SAndroid Build Coastguard Worker     if (rv == ERR_IO_PENDING)
394*6777b538SAndroid Build Coastguard Worker       rv = callback.WaitForResult();
395*6777b538SAndroid Build Coastguard Worker     EXPECT_LE(0, rv);
396*6777b538SAndroid Build Coastguard Worker     if (rv <= 0)
397*6777b538SAndroid Build Coastguard Worker       break;
398*6777b538SAndroid Build Coastguard Worker     total_bytes_read += rv;
399*6777b538SAndroid Build Coastguard Worker     data_read.append(buf->data(), rv);
400*6777b538SAndroid Build Coastguard Worker   }
401*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(file_size, total_bytes_read);
402*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(data_read == kTestData);
403*6777b538SAndroid Build Coastguard Worker 
404*6777b538SAndroid Build Coastguard Worker   int total_bytes_written = 0;
405*6777b538SAndroid Build Coastguard Worker 
406*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBufferWithSize> buffer = CreateTestDataBuffer();
407*6777b538SAndroid Build Coastguard Worker   int buffer_size = buffer->size();
408*6777b538SAndroid Build Coastguard Worker   scoped_refptr<DrainableIOBuffer> drainable =
409*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<DrainableIOBuffer>(std::move(buffer), buffer_size);
410*6777b538SAndroid Build Coastguard Worker   while (total_bytes_written != kTestDataSize) {
411*6777b538SAndroid Build Coastguard Worker     rv = stream->Write(drainable.get(), drainable->BytesRemaining(),
412*6777b538SAndroid Build Coastguard Worker                        callback.callback());
413*6777b538SAndroid Build Coastguard Worker     if (rv == ERR_IO_PENDING)
414*6777b538SAndroid Build Coastguard Worker       rv = callback.WaitForResult();
415*6777b538SAndroid Build Coastguard Worker     EXPECT_LT(0, rv);
416*6777b538SAndroid Build Coastguard Worker     if (rv <= 0)
417*6777b538SAndroid Build Coastguard Worker       break;
418*6777b538SAndroid Build Coastguard Worker     drainable->DidConsume(rv);
419*6777b538SAndroid Build Coastguard Worker     total_bytes_written += rv;
420*6777b538SAndroid Build Coastguard Worker   }
421*6777b538SAndroid Build Coastguard Worker 
422*6777b538SAndroid Build Coastguard Worker   stream.reset();
423*6777b538SAndroid Build Coastguard Worker 
424*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
425*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kTestDataSize * 2, file_size);
426*6777b538SAndroid Build Coastguard Worker }
427*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileStreamTest,BasicWriteRead)428*6777b538SAndroid Build Coastguard Worker TEST_F(FileStreamTest, BasicWriteRead) {
429*6777b538SAndroid Build Coastguard Worker   int64_t file_size;
430*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
431*6777b538SAndroid Build Coastguard Worker 
432*6777b538SAndroid Build Coastguard Worker   auto stream = std::make_unique<FileStream>(
433*6777b538SAndroid Build Coastguard Worker       base::SingleThreadTaskRunner::GetCurrentDefault());
434*6777b538SAndroid Build Coastguard Worker   int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
435*6777b538SAndroid Build Coastguard Worker               base::File::FLAG_WRITE | base::File::FLAG_ASYNC;
436*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
437*6777b538SAndroid Build Coastguard Worker   int rv = stream->Open(temp_file_path(), flags, callback.callback());
438*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
439*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(callback.WaitForResult(), IsOk());
440*6777b538SAndroid Build Coastguard Worker 
441*6777b538SAndroid Build Coastguard Worker   TestInt64CompletionCallback callback64;
442*6777b538SAndroid Build Coastguard Worker   rv = stream->Seek(file_size, callback64.callback());
443*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
444*6777b538SAndroid Build Coastguard Worker   int64_t offset = callback64.WaitForResult();
445*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(offset, file_size);
446*6777b538SAndroid Build Coastguard Worker 
447*6777b538SAndroid Build Coastguard Worker   int total_bytes_written = 0;
448*6777b538SAndroid Build Coastguard Worker 
449*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBufferWithSize> buffer = CreateTestDataBuffer();
450*6777b538SAndroid Build Coastguard Worker   int buffer_size = buffer->size();
451*6777b538SAndroid Build Coastguard Worker   scoped_refptr<DrainableIOBuffer> drainable =
452*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<DrainableIOBuffer>(std::move(buffer), buffer_size);
453*6777b538SAndroid Build Coastguard Worker   while (total_bytes_written != kTestDataSize) {
454*6777b538SAndroid Build Coastguard Worker     rv = stream->Write(drainable.get(), drainable->BytesRemaining(),
455*6777b538SAndroid Build Coastguard Worker                        callback.callback());
456*6777b538SAndroid Build Coastguard Worker     if (rv == ERR_IO_PENDING)
457*6777b538SAndroid Build Coastguard Worker       rv = callback.WaitForResult();
458*6777b538SAndroid Build Coastguard Worker     EXPECT_LT(0, rv);
459*6777b538SAndroid Build Coastguard Worker     if (rv <= 0)
460*6777b538SAndroid Build Coastguard Worker       break;
461*6777b538SAndroid Build Coastguard Worker     drainable->DidConsume(rv);
462*6777b538SAndroid Build Coastguard Worker     total_bytes_written += rv;
463*6777b538SAndroid Build Coastguard Worker   }
464*6777b538SAndroid Build Coastguard Worker 
465*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kTestDataSize, total_bytes_written);
466*6777b538SAndroid Build Coastguard Worker 
467*6777b538SAndroid Build Coastguard Worker   rv = stream->Seek(0, callback64.callback());
468*6777b538SAndroid Build Coastguard Worker   ASSERT_THAT(rv, IsError(ERR_IO_PENDING));
469*6777b538SAndroid Build Coastguard Worker   offset = callback64.WaitForResult();
470*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(0, offset);
471*6777b538SAndroid Build Coastguard Worker 
472*6777b538SAndroid Build Coastguard Worker   int total_bytes_read = 0;
473*6777b538SAndroid Build Coastguard Worker 
474*6777b538SAndroid Build Coastguard Worker   std::string data_read;
475*6777b538SAndroid Build Coastguard Worker   for (;;) {
476*6777b538SAndroid Build Coastguard Worker     scoped_refptr<IOBufferWithSize> buf =
477*6777b538SAndroid Build Coastguard Worker         base::MakeRefCounted<IOBufferWithSize>(4);
478*6777b538SAndroid Build Coastguard Worker     rv = stream->Read(buf.get(), buf->size(), callback.callback());
479*6777b538SAndroid Build Coastguard Worker     if (rv == ERR_IO_PENDING)
480*6777b538SAndroid Build Coastguard Worker       rv = callback.WaitForResult();
481*6777b538SAndroid Build Coastguard Worker     EXPECT_LE(0, rv);
482*6777b538SAndroid Build Coastguard Worker     if (rv <= 0)
483*6777b538SAndroid Build Coastguard Worker       break;
484*6777b538SAndroid Build Coastguard Worker     total_bytes_read += rv;
485*6777b538SAndroid Build Coastguard Worker     data_read.append(buf->data(), rv);
486*6777b538SAndroid Build Coastguard Worker   }
487*6777b538SAndroid Build Coastguard Worker   stream.reset();
488*6777b538SAndroid Build Coastguard Worker 
489*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
490*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kTestDataSize * 2, file_size);
491*6777b538SAndroid Build Coastguard Worker 
492*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
493*6777b538SAndroid Build Coastguard Worker   const std::string kExpectedFileData =
494*6777b538SAndroid Build Coastguard Worker       std::string(kTestData) + std::string(kTestData);
495*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kExpectedFileData, data_read);
496*6777b538SAndroid Build Coastguard Worker }
497*6777b538SAndroid Build Coastguard Worker 
498*6777b538SAndroid Build Coastguard Worker class TestWriteReadCompletionCallback {
499*6777b538SAndroid Build Coastguard Worker  public:
TestWriteReadCompletionCallback(FileStream * stream,int * total_bytes_written,int * total_bytes_read,std::string * data_read)500*6777b538SAndroid Build Coastguard Worker   TestWriteReadCompletionCallback(FileStream* stream,
501*6777b538SAndroid Build Coastguard Worker                                   int* total_bytes_written,
502*6777b538SAndroid Build Coastguard Worker                                   int* total_bytes_read,
503*6777b538SAndroid Build Coastguard Worker                                   std::string* data_read)
504*6777b538SAndroid Build Coastguard Worker       : stream_(stream),
505*6777b538SAndroid Build Coastguard Worker         total_bytes_written_(total_bytes_written),
506*6777b538SAndroid Build Coastguard Worker         total_bytes_read_(total_bytes_read),
507*6777b538SAndroid Build Coastguard Worker         data_read_(data_read),
508*6777b538SAndroid Build Coastguard Worker         drainable_(
509*6777b538SAndroid Build Coastguard Worker             base::MakeRefCounted<DrainableIOBuffer>(CreateTestDataBuffer(),
510*6777b538SAndroid Build Coastguard Worker                                                     kTestDataSize)) {}
511*6777b538SAndroid Build Coastguard Worker 
512*6777b538SAndroid Build Coastguard Worker   TestWriteReadCompletionCallback(const TestWriteReadCompletionCallback&) =
513*6777b538SAndroid Build Coastguard Worker       delete;
514*6777b538SAndroid Build Coastguard Worker   TestWriteReadCompletionCallback& operator=(
515*6777b538SAndroid Build Coastguard Worker       const TestWriteReadCompletionCallback&) = delete;
516*6777b538SAndroid Build Coastguard Worker 
WaitForResult()517*6777b538SAndroid Build Coastguard Worker   int WaitForResult() {
518*6777b538SAndroid Build Coastguard Worker     DCHECK(!waiting_for_result_);
519*6777b538SAndroid Build Coastguard Worker     while (!have_result_) {
520*6777b538SAndroid Build Coastguard Worker       base::RunLoop loop;
521*6777b538SAndroid Build Coastguard Worker       quit_closure_ = loop.QuitWhenIdleClosure();
522*6777b538SAndroid Build Coastguard Worker       waiting_for_result_ = true;
523*6777b538SAndroid Build Coastguard Worker       loop.Run();
524*6777b538SAndroid Build Coastguard Worker       waiting_for_result_ = false;
525*6777b538SAndroid Build Coastguard Worker     }
526*6777b538SAndroid Build Coastguard Worker     have_result_ = false;  // auto-reset for next callback
527*6777b538SAndroid Build Coastguard Worker     return result_;
528*6777b538SAndroid Build Coastguard Worker   }
529*6777b538SAndroid Build Coastguard Worker 
callback()530*6777b538SAndroid Build Coastguard Worker   CompletionOnceCallback callback() {
531*6777b538SAndroid Build Coastguard Worker     return base::BindOnce(&TestWriteReadCompletionCallback::OnComplete,
532*6777b538SAndroid Build Coastguard Worker                           base::Unretained(this));
533*6777b538SAndroid Build Coastguard Worker   }
534*6777b538SAndroid Build Coastguard Worker 
ValidateWrittenData()535*6777b538SAndroid Build Coastguard Worker   void ValidateWrittenData() {
536*6777b538SAndroid Build Coastguard Worker     TestCompletionCallback callback;
537*6777b538SAndroid Build Coastguard Worker     int rv = 0;
538*6777b538SAndroid Build Coastguard Worker     for (;;) {
539*6777b538SAndroid Build Coastguard Worker       scoped_refptr<IOBufferWithSize> buf =
540*6777b538SAndroid Build Coastguard Worker           base::MakeRefCounted<IOBufferWithSize>(4);
541*6777b538SAndroid Build Coastguard Worker       rv = stream_->Read(buf.get(), buf->size(), callback.callback());
542*6777b538SAndroid Build Coastguard Worker       if (rv == ERR_IO_PENDING) {
543*6777b538SAndroid Build Coastguard Worker         rv = callback.WaitForResult();
544*6777b538SAndroid Build Coastguard Worker       }
545*6777b538SAndroid Build Coastguard Worker       EXPECT_LE(0, rv);
546*6777b538SAndroid Build Coastguard Worker       if (rv <= 0)
547*6777b538SAndroid Build Coastguard Worker         break;
548*6777b538SAndroid Build Coastguard Worker       *total_bytes_read_ += rv;
549*6777b538SAndroid Build Coastguard Worker       data_read_->append(buf->data(), rv);
550*6777b538SAndroid Build Coastguard Worker     }
551*6777b538SAndroid Build Coastguard Worker   }
552*6777b538SAndroid Build Coastguard Worker 
553*6777b538SAndroid Build Coastguard Worker  private:
OnComplete(int result)554*6777b538SAndroid Build Coastguard Worker   void OnComplete(int result) {
555*6777b538SAndroid Build Coastguard Worker     DCHECK_LT(0, result);
556*6777b538SAndroid Build Coastguard Worker     *total_bytes_written_ += result;
557*6777b538SAndroid Build Coastguard Worker 
558*6777b538SAndroid Build Coastguard Worker     int rv;
559*6777b538SAndroid Build Coastguard Worker 
560*6777b538SAndroid Build Coastguard Worker     if (*total_bytes_written_ != kTestDataSize) {
561*6777b538SAndroid Build Coastguard Worker       // Recurse to finish writing all data.
562*6777b538SAndroid Build Coastguard Worker       int total_bytes_written = 0, total_bytes_read = 0;
563*6777b538SAndroid Build Coastguard Worker       std::string data_read;
564*6777b538SAndroid Build Coastguard Worker       TestWriteReadCompletionCallback callback(
565*6777b538SAndroid Build Coastguard Worker           stream_, &total_bytes_written, &total_bytes_read, &data_read);
566*6777b538SAndroid Build Coastguard Worker       rv = stream_->Write(
567*6777b538SAndroid Build Coastguard Worker           drainable_.get(), drainable_->BytesRemaining(), callback.callback());
568*6777b538SAndroid Build Coastguard Worker       DCHECK_EQ(ERR_IO_PENDING, rv);
569*6777b538SAndroid Build Coastguard Worker       rv = callback.WaitForResult();
570*6777b538SAndroid Build Coastguard Worker       drainable_->DidConsume(total_bytes_written);
571*6777b538SAndroid Build Coastguard Worker       *total_bytes_written_ += total_bytes_written;
572*6777b538SAndroid Build Coastguard Worker       *total_bytes_read_ += total_bytes_read;
573*6777b538SAndroid Build Coastguard Worker       *data_read_ += data_read;
574*6777b538SAndroid Build Coastguard Worker     } else {  // We're done writing all data.  Start reading the data.
575*6777b538SAndroid Build Coastguard Worker       TestInt64CompletionCallback callback64;
576*6777b538SAndroid Build Coastguard Worker       EXPECT_THAT(stream_->Seek(0, callback64.callback()),
577*6777b538SAndroid Build Coastguard Worker                   IsError(ERR_IO_PENDING));
578*6777b538SAndroid Build Coastguard Worker       {
579*6777b538SAndroid Build Coastguard Worker         EXPECT_LE(0, callback64.WaitForResult());
580*6777b538SAndroid Build Coastguard Worker       }
581*6777b538SAndroid Build Coastguard Worker     }
582*6777b538SAndroid Build Coastguard Worker 
583*6777b538SAndroid Build Coastguard Worker     result_ = *total_bytes_written_;
584*6777b538SAndroid Build Coastguard Worker     have_result_ = true;
585*6777b538SAndroid Build Coastguard Worker     if (waiting_for_result_)
586*6777b538SAndroid Build Coastguard Worker       std::move(quit_closure_).Run();
587*6777b538SAndroid Build Coastguard Worker   }
588*6777b538SAndroid Build Coastguard Worker 
589*6777b538SAndroid Build Coastguard Worker   int result_ = 0;
590*6777b538SAndroid Build Coastguard Worker   bool have_result_ = false;
591*6777b538SAndroid Build Coastguard Worker   bool waiting_for_result_ = false;
592*6777b538SAndroid Build Coastguard Worker   raw_ptr<FileStream> stream_;
593*6777b538SAndroid Build Coastguard Worker   raw_ptr<int> total_bytes_written_;
594*6777b538SAndroid Build Coastguard Worker   raw_ptr<int> total_bytes_read_;
595*6777b538SAndroid Build Coastguard Worker   raw_ptr<std::string> data_read_;
596*6777b538SAndroid Build Coastguard Worker   scoped_refptr<DrainableIOBuffer> drainable_;
597*6777b538SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
598*6777b538SAndroid Build Coastguard Worker };
599*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileStreamTest,WriteRead)600*6777b538SAndroid Build Coastguard Worker TEST_F(FileStreamTest, WriteRead) {
601*6777b538SAndroid Build Coastguard Worker   int64_t file_size;
602*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
603*6777b538SAndroid Build Coastguard Worker 
604*6777b538SAndroid Build Coastguard Worker   auto stream = std::make_unique<FileStream>(
605*6777b538SAndroid Build Coastguard Worker       base::SingleThreadTaskRunner::GetCurrentDefault());
606*6777b538SAndroid Build Coastguard Worker   int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
607*6777b538SAndroid Build Coastguard Worker               base::File::FLAG_WRITE | base::File::FLAG_ASYNC;
608*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback open_callback;
609*6777b538SAndroid Build Coastguard Worker   int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
610*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
611*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(open_callback.WaitForResult(), IsOk());
612*6777b538SAndroid Build Coastguard Worker 
613*6777b538SAndroid Build Coastguard Worker   TestInt64CompletionCallback callback64;
614*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(stream->Seek(file_size, callback64.callback()),
615*6777b538SAndroid Build Coastguard Worker               IsError(ERR_IO_PENDING));
616*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(file_size, callback64.WaitForResult());
617*6777b538SAndroid Build Coastguard Worker 
618*6777b538SAndroid Build Coastguard Worker   int total_bytes_written = 0;
619*6777b538SAndroid Build Coastguard Worker   int total_bytes_read = 0;
620*6777b538SAndroid Build Coastguard Worker   std::string data_read;
621*6777b538SAndroid Build Coastguard Worker   {
622*6777b538SAndroid Build Coastguard Worker     // `callback` can't outlive `stream`.
623*6777b538SAndroid Build Coastguard Worker     TestWriteReadCompletionCallback callback(stream.get(), &total_bytes_written,
624*6777b538SAndroid Build Coastguard Worker                                              &total_bytes_read, &data_read);
625*6777b538SAndroid Build Coastguard Worker 
626*6777b538SAndroid Build Coastguard Worker     scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
627*6777b538SAndroid Build Coastguard Worker     rv = stream->Write(buf.get(), buf->size(), callback.callback());
628*6777b538SAndroid Build Coastguard Worker     if (rv == ERR_IO_PENDING) {
629*6777b538SAndroid Build Coastguard Worker       rv = callback.WaitForResult();
630*6777b538SAndroid Build Coastguard Worker     }
631*6777b538SAndroid Build Coastguard Worker     EXPECT_LT(0, rv);
632*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kTestDataSize, total_bytes_written);
633*6777b538SAndroid Build Coastguard Worker 
634*6777b538SAndroid Build Coastguard Worker     callback.ValidateWrittenData();
635*6777b538SAndroid Build Coastguard Worker   }
636*6777b538SAndroid Build Coastguard Worker   stream.reset();
637*6777b538SAndroid Build Coastguard Worker 
638*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
639*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kTestDataSize * 2, file_size);
640*6777b538SAndroid Build Coastguard Worker 
641*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
642*6777b538SAndroid Build Coastguard Worker   const std::string kExpectedFileData =
643*6777b538SAndroid Build Coastguard Worker       std::string(kTestData) + std::string(kTestData);
644*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kExpectedFileData, data_read);
645*6777b538SAndroid Build Coastguard Worker }
646*6777b538SAndroid Build Coastguard Worker 
647*6777b538SAndroid Build Coastguard Worker class TestWriteCloseCompletionCallback {
648*6777b538SAndroid Build Coastguard Worker  public:
TestWriteCloseCompletionCallback(FileStream * stream,int * total_bytes_written)649*6777b538SAndroid Build Coastguard Worker   TestWriteCloseCompletionCallback(FileStream* stream, int* total_bytes_written)
650*6777b538SAndroid Build Coastguard Worker       : stream_(stream),
651*6777b538SAndroid Build Coastguard Worker         total_bytes_written_(total_bytes_written),
652*6777b538SAndroid Build Coastguard Worker         drainable_(
653*6777b538SAndroid Build Coastguard Worker             base::MakeRefCounted<DrainableIOBuffer>(CreateTestDataBuffer(),
654*6777b538SAndroid Build Coastguard Worker                                                     kTestDataSize)) {}
655*6777b538SAndroid Build Coastguard Worker   TestWriteCloseCompletionCallback(const TestWriteCloseCompletionCallback&) =
656*6777b538SAndroid Build Coastguard Worker       delete;
657*6777b538SAndroid Build Coastguard Worker   TestWriteCloseCompletionCallback& operator=(
658*6777b538SAndroid Build Coastguard Worker       const TestWriteCloseCompletionCallback&) = delete;
659*6777b538SAndroid Build Coastguard Worker 
WaitForResult()660*6777b538SAndroid Build Coastguard Worker   int WaitForResult() {
661*6777b538SAndroid Build Coastguard Worker     DCHECK(!waiting_for_result_);
662*6777b538SAndroid Build Coastguard Worker     while (!have_result_) {
663*6777b538SAndroid Build Coastguard Worker       base::RunLoop loop;
664*6777b538SAndroid Build Coastguard Worker       quit_closure_ = loop.QuitWhenIdleClosure();
665*6777b538SAndroid Build Coastguard Worker       waiting_for_result_ = true;
666*6777b538SAndroid Build Coastguard Worker       loop.Run();
667*6777b538SAndroid Build Coastguard Worker       waiting_for_result_ = false;
668*6777b538SAndroid Build Coastguard Worker     }
669*6777b538SAndroid Build Coastguard Worker     have_result_ = false;  // auto-reset for next callback
670*6777b538SAndroid Build Coastguard Worker     return result_;
671*6777b538SAndroid Build Coastguard Worker   }
672*6777b538SAndroid Build Coastguard Worker 
callback()673*6777b538SAndroid Build Coastguard Worker   CompletionOnceCallback callback() {
674*6777b538SAndroid Build Coastguard Worker     return base::BindOnce(&TestWriteCloseCompletionCallback::OnComplete,
675*6777b538SAndroid Build Coastguard Worker                           base::Unretained(this));
676*6777b538SAndroid Build Coastguard Worker   }
677*6777b538SAndroid Build Coastguard Worker 
678*6777b538SAndroid Build Coastguard Worker  private:
OnComplete(int result)679*6777b538SAndroid Build Coastguard Worker   void OnComplete(int result) {
680*6777b538SAndroid Build Coastguard Worker     DCHECK_LT(0, result);
681*6777b538SAndroid Build Coastguard Worker     *total_bytes_written_ += result;
682*6777b538SAndroid Build Coastguard Worker 
683*6777b538SAndroid Build Coastguard Worker     int rv;
684*6777b538SAndroid Build Coastguard Worker 
685*6777b538SAndroid Build Coastguard Worker     if (*total_bytes_written_ != kTestDataSize) {
686*6777b538SAndroid Build Coastguard Worker       // Recurse to finish writing all data.
687*6777b538SAndroid Build Coastguard Worker       int total_bytes_written = 0;
688*6777b538SAndroid Build Coastguard Worker       TestWriteCloseCompletionCallback callback(stream_, &total_bytes_written);
689*6777b538SAndroid Build Coastguard Worker       rv = stream_->Write(
690*6777b538SAndroid Build Coastguard Worker           drainable_.get(), drainable_->BytesRemaining(), callback.callback());
691*6777b538SAndroid Build Coastguard Worker       DCHECK_EQ(ERR_IO_PENDING, rv);
692*6777b538SAndroid Build Coastguard Worker       rv = callback.WaitForResult();
693*6777b538SAndroid Build Coastguard Worker       drainable_->DidConsume(total_bytes_written);
694*6777b538SAndroid Build Coastguard Worker       *total_bytes_written_ += total_bytes_written;
695*6777b538SAndroid Build Coastguard Worker     }
696*6777b538SAndroid Build Coastguard Worker 
697*6777b538SAndroid Build Coastguard Worker     result_ = *total_bytes_written_;
698*6777b538SAndroid Build Coastguard Worker     have_result_ = true;
699*6777b538SAndroid Build Coastguard Worker     if (waiting_for_result_)
700*6777b538SAndroid Build Coastguard Worker       std::move(quit_closure_).Run();
701*6777b538SAndroid Build Coastguard Worker   }
702*6777b538SAndroid Build Coastguard Worker 
703*6777b538SAndroid Build Coastguard Worker   int result_ = 0;
704*6777b538SAndroid Build Coastguard Worker   bool have_result_ = false;
705*6777b538SAndroid Build Coastguard Worker   bool waiting_for_result_ = false;
706*6777b538SAndroid Build Coastguard Worker   raw_ptr<FileStream> stream_;
707*6777b538SAndroid Build Coastguard Worker   raw_ptr<int> total_bytes_written_;
708*6777b538SAndroid Build Coastguard Worker   scoped_refptr<DrainableIOBuffer> drainable_;
709*6777b538SAndroid Build Coastguard Worker   base::OnceClosure quit_closure_;
710*6777b538SAndroid Build Coastguard Worker };
711*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileStreamTest,WriteClose)712*6777b538SAndroid Build Coastguard Worker TEST_F(FileStreamTest, WriteClose) {
713*6777b538SAndroid Build Coastguard Worker   int64_t file_size;
714*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
715*6777b538SAndroid Build Coastguard Worker 
716*6777b538SAndroid Build Coastguard Worker   auto stream = std::make_unique<FileStream>(
717*6777b538SAndroid Build Coastguard Worker       base::SingleThreadTaskRunner::GetCurrentDefault());
718*6777b538SAndroid Build Coastguard Worker   int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
719*6777b538SAndroid Build Coastguard Worker               base::File::FLAG_WRITE | base::File::FLAG_ASYNC;
720*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback open_callback;
721*6777b538SAndroid Build Coastguard Worker   int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
722*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
723*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(open_callback.WaitForResult(), IsOk());
724*6777b538SAndroid Build Coastguard Worker 
725*6777b538SAndroid Build Coastguard Worker   TestInt64CompletionCallback callback64;
726*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(stream->Seek(file_size, callback64.callback()),
727*6777b538SAndroid Build Coastguard Worker               IsError(ERR_IO_PENDING));
728*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(file_size, callback64.WaitForResult());
729*6777b538SAndroid Build Coastguard Worker 
730*6777b538SAndroid Build Coastguard Worker   int total_bytes_written = 0;
731*6777b538SAndroid Build Coastguard Worker   {
732*6777b538SAndroid Build Coastguard Worker     // `callback` can't outlive `stream`.
733*6777b538SAndroid Build Coastguard Worker     TestWriteCloseCompletionCallback callback(stream.get(),
734*6777b538SAndroid Build Coastguard Worker                                               &total_bytes_written);
735*6777b538SAndroid Build Coastguard Worker     scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
736*6777b538SAndroid Build Coastguard Worker     rv = stream->Write(buf.get(), buf->size(), callback.callback());
737*6777b538SAndroid Build Coastguard Worker     if (rv == ERR_IO_PENDING) {
738*6777b538SAndroid Build Coastguard Worker       total_bytes_written = callback.WaitForResult();
739*6777b538SAndroid Build Coastguard Worker     }
740*6777b538SAndroid Build Coastguard Worker     EXPECT_LT(0, total_bytes_written);
741*6777b538SAndroid Build Coastguard Worker     EXPECT_EQ(kTestDataSize, total_bytes_written);
742*6777b538SAndroid Build Coastguard Worker   }
743*6777b538SAndroid Build Coastguard Worker   stream.reset();
744*6777b538SAndroid Build Coastguard Worker 
745*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
746*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(kTestDataSize * 2, file_size);
747*6777b538SAndroid Build Coastguard Worker }
748*6777b538SAndroid Build Coastguard Worker 
TEST_F(FileStreamTest,OpenAndDelete)749*6777b538SAndroid Build Coastguard Worker TEST_F(FileStreamTest, OpenAndDelete) {
750*6777b538SAndroid Build Coastguard Worker   base::Thread worker_thread("StreamTest");
751*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(worker_thread.Start());
752*6777b538SAndroid Build Coastguard Worker 
753*6777b538SAndroid Build Coastguard Worker   base::ScopedDisallowBlocking disallow_blocking;
754*6777b538SAndroid Build Coastguard Worker   auto stream = std::make_unique<FileStream>(worker_thread.task_runner());
755*6777b538SAndroid Build Coastguard Worker   int flags = base::File::FLAG_OPEN | base::File::FLAG_WRITE |
756*6777b538SAndroid Build Coastguard Worker               base::File::FLAG_ASYNC;
757*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback open_callback;
758*6777b538SAndroid Build Coastguard Worker   int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
759*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
760*6777b538SAndroid Build Coastguard Worker 
761*6777b538SAndroid Build Coastguard Worker   // Delete the stream without waiting for the open operation to be
762*6777b538SAndroid Build Coastguard Worker   // complete. Should be safe.
763*6777b538SAndroid Build Coastguard Worker   stream.reset();
764*6777b538SAndroid Build Coastguard Worker 
765*6777b538SAndroid Build Coastguard Worker   // Force an operation through the worker.
766*6777b538SAndroid Build Coastguard Worker   auto stream2 = std::make_unique<FileStream>(worker_thread.task_runner());
767*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback open_callback2;
768*6777b538SAndroid Build Coastguard Worker   rv = stream2->Open(temp_file_path(), flags, open_callback2.callback());
769*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(open_callback2.GetResult(rv), IsOk());
770*6777b538SAndroid Build Coastguard Worker   stream2.reset();
771*6777b538SAndroid Build Coastguard Worker 
772*6777b538SAndroid Build Coastguard Worker   // open_callback won't be called.
773*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
774*6777b538SAndroid Build Coastguard Worker   EXPECT_FALSE(open_callback.have_result());
775*6777b538SAndroid Build Coastguard Worker }
776*6777b538SAndroid Build Coastguard Worker 
777*6777b538SAndroid Build Coastguard Worker // Verify that Write() errors are mapped correctly.
TEST_F(FileStreamTest,WriteError)778*6777b538SAndroid Build Coastguard Worker TEST_F(FileStreamTest, WriteError) {
779*6777b538SAndroid Build Coastguard Worker   // Try opening file as read-only and then writing to it using FileStream.
780*6777b538SAndroid Build Coastguard Worker   uint32_t flags =
781*6777b538SAndroid Build Coastguard Worker       base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_ASYNC;
782*6777b538SAndroid Build Coastguard Worker 
783*6777b538SAndroid Build Coastguard Worker   base::File file(temp_file_path(), flags);
784*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(file.IsValid());
785*6777b538SAndroid Build Coastguard Worker 
786*6777b538SAndroid Build Coastguard Worker   auto stream = std::make_unique<FileStream>(
787*6777b538SAndroid Build Coastguard Worker       std::move(file), base::SingleThreadTaskRunner::GetCurrentDefault());
788*6777b538SAndroid Build Coastguard Worker 
789*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBufferWithSize>(1);
790*6777b538SAndroid Build Coastguard Worker   buf->data()[0] = 0;
791*6777b538SAndroid Build Coastguard Worker 
792*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
793*6777b538SAndroid Build Coastguard Worker   int rv = stream->Write(buf.get(), 1, callback.callback());
794*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING)
795*6777b538SAndroid Build Coastguard Worker     rv = callback.WaitForResult();
796*6777b538SAndroid Build Coastguard Worker   EXPECT_LT(rv, 0);
797*6777b538SAndroid Build Coastguard Worker 
798*6777b538SAndroid Build Coastguard Worker   stream.reset();
799*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
800*6777b538SAndroid Build Coastguard Worker }
801*6777b538SAndroid Build Coastguard Worker 
802*6777b538SAndroid Build Coastguard Worker // Verify that Read() errors are mapped correctly.
TEST_F(FileStreamTest,ReadError)803*6777b538SAndroid Build Coastguard Worker TEST_F(FileStreamTest, ReadError) {
804*6777b538SAndroid Build Coastguard Worker   // Try opening file for write and then reading from it using FileStream.
805*6777b538SAndroid Build Coastguard Worker   uint32_t flags =
806*6777b538SAndroid Build Coastguard Worker       base::File::FLAG_OPEN | base::File::FLAG_WRITE | base::File::FLAG_ASYNC;
807*6777b538SAndroid Build Coastguard Worker 
808*6777b538SAndroid Build Coastguard Worker   base::File file(temp_file_path(), flags);
809*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(file.IsValid());
810*6777b538SAndroid Build Coastguard Worker 
811*6777b538SAndroid Build Coastguard Worker   auto stream = std::make_unique<FileStream>(
812*6777b538SAndroid Build Coastguard Worker       std::move(file), base::SingleThreadTaskRunner::GetCurrentDefault());
813*6777b538SAndroid Build Coastguard Worker 
814*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBuffer> buf = base::MakeRefCounted<IOBufferWithSize>(1);
815*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
816*6777b538SAndroid Build Coastguard Worker   int rv = stream->Read(buf.get(), 1, callback.callback());
817*6777b538SAndroid Build Coastguard Worker   if (rv == ERR_IO_PENDING)
818*6777b538SAndroid Build Coastguard Worker     rv = callback.WaitForResult();
819*6777b538SAndroid Build Coastguard Worker   EXPECT_LT(rv, 0);
820*6777b538SAndroid Build Coastguard Worker 
821*6777b538SAndroid Build Coastguard Worker   stream.reset();
822*6777b538SAndroid Build Coastguard Worker   base::RunLoop().RunUntilIdle();
823*6777b538SAndroid Build Coastguard Worker }
824*6777b538SAndroid Build Coastguard Worker 
825*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_WIN)
826*6777b538SAndroid Build Coastguard Worker // Verifies that a FileStream will close itself if it receives a File whose
827*6777b538SAndroid Build Coastguard Worker // async flag doesn't match the async state of the underlying handle.
TEST_F(FileStreamTest,AsyncFlagMismatch)828*6777b538SAndroid Build Coastguard Worker TEST_F(FileStreamTest, AsyncFlagMismatch) {
829*6777b538SAndroid Build Coastguard Worker   // Open the test file without async, then make a File with the same sync
830*6777b538SAndroid Build Coastguard Worker   // handle but with the async flag set to true.
831*6777b538SAndroid Build Coastguard Worker   uint32_t flags = base::File::FLAG_OPEN | base::File::FLAG_READ;
832*6777b538SAndroid Build Coastguard Worker   base::File file(temp_file_path(), flags);
833*6777b538SAndroid Build Coastguard Worker   base::File lying_file(file.TakePlatformFile(), true);
834*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(lying_file.IsValid());
835*6777b538SAndroid Build Coastguard Worker 
836*6777b538SAndroid Build Coastguard Worker   FileStream stream(std::move(lying_file),
837*6777b538SAndroid Build Coastguard Worker                     base::SingleThreadTaskRunner::GetCurrentDefault());
838*6777b538SAndroid Build Coastguard Worker   ASSERT_FALSE(stream.IsOpen());
839*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
840*6777b538SAndroid Build Coastguard Worker   scoped_refptr<IOBufferWithSize> buf =
841*6777b538SAndroid Build Coastguard Worker       base::MakeRefCounted<IOBufferWithSize>(4);
842*6777b538SAndroid Build Coastguard Worker   int rv = stream.Read(buf.get(), buf->size(), callback.callback());
843*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(callback.GetResult(rv), IsError(ERR_UNEXPECTED));
844*6777b538SAndroid Build Coastguard Worker }
845*6777b538SAndroid Build Coastguard Worker #endif
846*6777b538SAndroid Build Coastguard Worker 
847*6777b538SAndroid Build Coastguard Worker #if BUILDFLAG(IS_ANDROID)
848*6777b538SAndroid Build Coastguard Worker // TODO(https://crbug.com/894599): flaky on both android and cronet bots.
TEST_F(FileStreamTest,DISABLED_ContentUriRead)849*6777b538SAndroid Build Coastguard Worker TEST_F(FileStreamTest, DISABLED_ContentUriRead) {
850*6777b538SAndroid Build Coastguard Worker   base::FilePath test_dir;
851*6777b538SAndroid Build Coastguard Worker   base::PathService::Get(base::DIR_SRC_TEST_DATA_ROOT, &test_dir);
852*6777b538SAndroid Build Coastguard Worker   test_dir = test_dir.AppendASCII("net");
853*6777b538SAndroid Build Coastguard Worker   test_dir = test_dir.AppendASCII("data");
854*6777b538SAndroid Build Coastguard Worker   test_dir = test_dir.AppendASCII("file_stream_unittest");
855*6777b538SAndroid Build Coastguard Worker   ASSERT_TRUE(base::PathExists(test_dir));
856*6777b538SAndroid Build Coastguard Worker   base::FilePath image_file = test_dir.Append(FILE_PATH_LITERAL("red.png"));
857*6777b538SAndroid Build Coastguard Worker 
858*6777b538SAndroid Build Coastguard Worker   // Insert the image into MediaStore. MediaStore will do some conversions, and
859*6777b538SAndroid Build Coastguard Worker   // return the content URI.
860*6777b538SAndroid Build Coastguard Worker   base::FilePath path = base::InsertImageIntoMediaStore(image_file);
861*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(path.IsContentUri());
862*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::PathExists(path));
863*6777b538SAndroid Build Coastguard Worker   int64_t file_size;
864*6777b538SAndroid Build Coastguard Worker   EXPECT_TRUE(base::GetFileSize(path, &file_size));
865*6777b538SAndroid Build Coastguard Worker   EXPECT_LT(0, file_size);
866*6777b538SAndroid Build Coastguard Worker 
867*6777b538SAndroid Build Coastguard Worker   FileStream stream(base::SingleThreadTaskRunner::GetCurrentDefault());
868*6777b538SAndroid Build Coastguard Worker   int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
869*6777b538SAndroid Build Coastguard Worker               base::File::FLAG_ASYNC;
870*6777b538SAndroid Build Coastguard Worker   TestCompletionCallback callback;
871*6777b538SAndroid Build Coastguard Worker   int rv = stream.Open(path, flags, callback.callback());
872*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(rv, IsError(ERR_IO_PENDING));
873*6777b538SAndroid Build Coastguard Worker   EXPECT_THAT(callback.WaitForResult(), IsOk());
874*6777b538SAndroid Build Coastguard Worker 
875*6777b538SAndroid Build Coastguard Worker   int total_bytes_read = 0;
876*6777b538SAndroid Build Coastguard Worker 
877*6777b538SAndroid Build Coastguard Worker   std::string data_read;
878*6777b538SAndroid Build Coastguard Worker   for (;;) {
879*6777b538SAndroid Build Coastguard Worker     scoped_refptr<IOBufferWithSize> buf =
880*6777b538SAndroid Build Coastguard Worker         base::MakeRefCounted<IOBufferWithSize>(4);
881*6777b538SAndroid Build Coastguard Worker     rv = stream.Read(buf.get(), buf->size(), callback.callback());
882*6777b538SAndroid Build Coastguard Worker     if (rv == ERR_IO_PENDING)
883*6777b538SAndroid Build Coastguard Worker       rv = callback.WaitForResult();
884*6777b538SAndroid Build Coastguard Worker     EXPECT_LE(0, rv);
885*6777b538SAndroid Build Coastguard Worker     if (rv <= 0)
886*6777b538SAndroid Build Coastguard Worker       break;
887*6777b538SAndroid Build Coastguard Worker     total_bytes_read += rv;
888*6777b538SAndroid Build Coastguard Worker     data_read.append(buf->data(), rv);
889*6777b538SAndroid Build Coastguard Worker   }
890*6777b538SAndroid Build Coastguard Worker   EXPECT_EQ(file_size, total_bytes_read);
891*6777b538SAndroid Build Coastguard Worker }
892*6777b538SAndroid Build Coastguard Worker #endif
893*6777b538SAndroid Build Coastguard Worker 
894*6777b538SAndroid Build Coastguard Worker }  // namespace
895*6777b538SAndroid Build Coastguard Worker 
896*6777b538SAndroid Build Coastguard Worker }  // namespace net
897