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