blob: a1e181557e68bada3e1004ede3670de4e1995ce6 [file] [log] [blame]
[email protected]10342992012-02-02 18:49:431// Copyright (c) 2012 The Chromium Authors. All rights reserved.
[email protected]2041cf342010-02-19 03:15:592// Use of this source code is governed by a BSD-style license that can be
3// found in the LICENSE file.
[email protected]21da6eb2008-11-03 17:18:144
[email protected]5eb431e22011-10-12 08:51:385#include "net/base/file_stream.h"
6
7#include "base/bind.h"
[email protected]2041cf342010-02-19 03:15:598#include "base/callback.h"
[email protected]a08305912014-03-21 00:41:159#include "base/files/file.h"
thestigd8df0332014-09-04 06:33:2910#include "base/files/file_util.h"
[email protected]5ee20982013-07-17 21:51:1811#include "base/message_loop/message_loop.h"
[email protected]21da6eb2008-11-03 17:18:1412#include "base/path_service.h"
[email protected]dd2c4382013-09-07 16:01:4713#include "base/run_loop.h"
[email protected]633ff3b12014-06-20 23:30:1814#include "base/strings/string_util.h"
[email protected]e3d66fde2012-02-17 22:10:3415#include "base/synchronization/waitable_event.h"
16#include "base/test/test_timeouts.h"
skyostil4891b25b2015-06-11 11:43:4517#include "base/thread_task_runner_handle.h"
[email protected]e3ec0625d2014-05-02 23:58:5418#include "base/threading/sequenced_worker_pool.h"
19#include "base/threading/thread_restrictions.h"
[email protected]9f49afb2012-02-16 09:59:2020#include "net/base/io_buffer.h"
[email protected]21da6eb2008-11-03 17:18:1421#include "net/base/net_errors.h"
22#include "net/base/test_completion_callback.h"
vishal.b62985ca92015-04-17 08:45:5123#include "net/log/test_net_log.h"
[email protected]21da6eb2008-11-03 17:18:1424#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1525#include "testing/platform_test.h"
[email protected]21da6eb2008-11-03 17:18:1426
[email protected]f12d1e12013-11-20 07:04:5527#if defined(OS_ANDROID)
28#include "base/test/test_file_util.h"
29#endif
30
[email protected]8effd3f62011-03-25 16:29:0731namespace net {
[email protected]96d73822011-10-10 02:11:2432
[email protected]4c2048a2009-03-24 21:02:0133namespace {
34
35const char kTestData[] = "0123456789";
36const int kTestDataSize = arraysize(kTestData) - 1;
[email protected]21da6eb2008-11-03 17:18:1437
[email protected]9f49afb2012-02-16 09:59:2038// Creates an IOBufferWithSize that contains the kTestDataSize.
39IOBufferWithSize* CreateTestDataBuffer() {
40 IOBufferWithSize* buf = new IOBufferWithSize(kTestDataSize);
41 memcpy(buf->data(), kTestData, kTestDataSize);
42 return buf;
43}
44
[email protected]96d73822011-10-10 02:11:2445} // namespace
46
[email protected]21da6eb2008-11-03 17:18:1447class FileStreamTest : public PlatformTest {
48 public:
dcheng67be2b1f2014-10-27 21:47:2949 void SetUp() override {
[email protected]21da6eb2008-11-03 17:18:1450 PlatformTest::SetUp();
51
[email protected]03d9afc02013-12-03 17:55:5252 base::CreateTemporaryFile(&temp_file_path_);
[email protected]e5c2a22e2014-03-06 20:42:3053 base::WriteFile(temp_file_path_, kTestData, kTestDataSize);
[email protected]21da6eb2008-11-03 17:18:1454 }
dcheng67be2b1f2014-10-27 21:47:2955 void TearDown() override {
[email protected]dd2c4382013-09-07 16:01:4756 // FileStreamContexts must be asynchronously closed on the file task runner
57 // before they can be deleted. Pump the RunLoop to avoid leaks.
58 base::RunLoop().RunUntilIdle();
[email protected]50f91af2014-04-09 17:28:5659 EXPECT_TRUE(base::DeleteFile(temp_file_path_, false));
60
[email protected]21da6eb2008-11-03 17:18:1461 PlatformTest::TearDown();
62 }
[email protected]96d73822011-10-10 02:11:2463
[email protected]6cdfd7f2013-02-08 20:40:1564 const base::FilePath temp_file_path() const { return temp_file_path_; }
[email protected]96d73822011-10-10 02:11:2465
[email protected]21da6eb2008-11-03 17:18:1466 private:
[email protected]6cdfd7f2013-02-08 20:40:1567 base::FilePath temp_file_path_;
[email protected]21da6eb2008-11-03 17:18:1468};
69
[email protected]96d73822011-10-10 02:11:2470namespace {
71
[email protected]633ff3b12014-06-20 23:30:1872TEST_F(FileStreamTest, OpenExplicitClose) {
[email protected]c1d9cf742013-09-12 06:37:1973 TestCompletionCallback callback;
skyostil4891b25b2015-06-11 11:43:4574 FileStream stream(base::ThreadTaskRunnerHandle::Get());
[email protected]a08305912014-03-21 00:41:1575 int flags = base::File::FLAG_OPEN |
76 base::File::FLAG_READ |
77 base::File::FLAG_ASYNC;
[email protected]c1d9cf742013-09-12 06:37:1978 int rv = stream.Open(temp_file_path(), flags, callback.callback());
79 EXPECT_EQ(ERR_IO_PENDING, rv);
80 EXPECT_EQ(OK, callback.WaitForResult());
81 EXPECT_TRUE(stream.IsOpen());
[email protected]a08305912014-03-21 00:41:1582 EXPECT_TRUE(stream.GetFileForTesting().IsValid());
[email protected]c1d9cf742013-09-12 06:37:1983 EXPECT_EQ(ERR_IO_PENDING, stream.Close(callback.callback()));
84 EXPECT_EQ(OK, callback.WaitForResult());
85 EXPECT_FALSE(stream.IsOpen());
[email protected]a08305912014-03-21 00:41:1586 EXPECT_FALSE(stream.GetFileForTesting().IsValid());
[email protected]c1d9cf742013-09-12 06:37:1987}
88
[email protected]633ff3b12014-06-20 23:30:1889TEST_F(FileStreamTest, OpenExplicitCloseOrphaned) {
[email protected]c1d9cf742013-09-12 06:37:1990 TestCompletionCallback callback;
skyostil4891b25b2015-06-11 11:43:4591 scoped_ptr<FileStream> stream(
92 new FileStream(base::ThreadTaskRunnerHandle::Get()));
[email protected]a08305912014-03-21 00:41:1593 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
94 base::File::FLAG_ASYNC;
[email protected]c1d9cf742013-09-12 06:37:1995 int rv = stream->Open(temp_file_path(), flags, callback.callback());
96 EXPECT_EQ(ERR_IO_PENDING, rv);
97 EXPECT_EQ(OK, callback.WaitForResult());
98 EXPECT_TRUE(stream->IsOpen());
[email protected]a08305912014-03-21 00:41:1599 EXPECT_TRUE(stream->GetFileForTesting().IsValid());
[email protected]c1d9cf742013-09-12 06:37:19100 EXPECT_EQ(ERR_IO_PENDING, stream->Close(callback.callback()));
101 stream.reset();
102 // File isn't actually closed yet.
[email protected]c1d9cf742013-09-12 06:37:19103 base::RunLoop runloop;
104 runloop.RunUntilIdle();
105 // The file should now be closed, though the callback has not been called.
[email protected]21da6eb2008-11-03 17:18:14106}
107
[email protected]92aad5222009-02-09 22:26:41108// Test the use of FileStream with a file handle provided at construction.
109TEST_F(FileStreamTest, UseFileHandle) {
[email protected]50f91af2014-04-09 17:28:56110 int rv = 0;
111 TestCompletionCallback callback;
112 TestInt64CompletionCallback callback64;
[email protected]92aad5222009-02-09 22:26:41113 // 1. Test reading with a file handle.
114 ASSERT_EQ(kTestDataSize,
[email protected]a08305912014-03-21 00:41:15115 base::WriteFile(temp_file_path(), kTestData, kTestDataSize));
[email protected]50f91af2014-04-09 17:28:56116 int flags = base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_READ |
117 base::File::FLAG_ASYNC;
[email protected]a08305912014-03-21 00:41:15118 base::File file(temp_file_path(), flags);
[email protected]92aad5222009-02-09 22:26:41119
120 // Seek to the beginning of the file and read.
[email protected]dd2c4382013-09-07 16:01:47121 scoped_ptr<FileStream> read_stream(
skyostil4891b25b2015-06-11 11:43:45122 new FileStream(file.Pass(), base::ThreadTaskRunnerHandle::Get()));
[email protected]50f91af2014-04-09 17:28:56123 ASSERT_EQ(ERR_IO_PENDING,
[email protected]633ff3b12014-06-20 23:30:18124 read_stream->Seek(base::File::FROM_BEGIN, 0,
125 callback64.callback()));
[email protected]50f91af2014-04-09 17:28:56126 ASSERT_EQ(0, callback64.WaitForResult());
[email protected]92aad5222009-02-09 22:26:41127 // Read into buffer and compare.
[email protected]50f91af2014-04-09 17:28:56128 scoped_refptr<IOBufferWithSize> read_buffer =
129 new IOBufferWithSize(kTestDataSize);
130 rv = read_stream->Read(read_buffer.get(), kTestDataSize, callback.callback());
131 ASSERT_EQ(kTestDataSize, callback.GetResult(rv));
132 ASSERT_EQ(0, memcmp(kTestData, read_buffer->data(), kTestDataSize));
[email protected]aab1b9e2012-11-06 00:29:51133 read_stream.reset();
[email protected]92aad5222009-02-09 22:26:41134
135 // 2. Test writing with a file handle.
[email protected]dd3aa792013-07-16 19:10:23136 base::DeleteFile(temp_file_path(), false);
[email protected]50f91af2014-04-09 17:28:56137 flags = base::File::FLAG_OPEN_ALWAYS | base::File::FLAG_WRITE |
138 base::File::FLAG_ASYNC;
[email protected]a08305912014-03-21 00:41:15139 file.Initialize(temp_file_path(), flags);
[email protected]92aad5222009-02-09 22:26:41140
[email protected]dd2c4382013-09-07 16:01:47141 scoped_ptr<FileStream> write_stream(
skyostil4891b25b2015-06-11 11:43:45142 new FileStream(file.Pass(), base::ThreadTaskRunnerHandle::Get()));
[email protected]50f91af2014-04-09 17:28:56143 ASSERT_EQ(ERR_IO_PENDING,
[email protected]633ff3b12014-06-20 23:30:18144 write_stream->Seek(base::File::FROM_BEGIN, 0,
145 callback64.callback()));
[email protected]50f91af2014-04-09 17:28:56146 ASSERT_EQ(0, callback64.WaitForResult());
147 scoped_refptr<IOBufferWithSize> write_buffer = CreateTestDataBuffer();
148 rv = write_stream->Write(write_buffer.get(), kTestDataSize,
149 callback.callback());
150 ASSERT_EQ(kTestDataSize, callback.GetResult(rv));
[email protected]aab1b9e2012-11-06 00:29:51151 write_stream.reset();
[email protected]92aad5222009-02-09 22:26:41152
153 // Read into buffer and compare to make sure the handle worked fine.
154 ASSERT_EQ(kTestDataSize,
[email protected]50f91af2014-04-09 17:28:56155 base::ReadFile(temp_file_path(), read_buffer->data(),
156 kTestDataSize));
157 ASSERT_EQ(0, memcmp(kTestData, read_buffer->data(), kTestDataSize));
[email protected]92aad5222009-02-09 22:26:41158}
159
[email protected]21da6eb2008-11-03 17:18:14160TEST_F(FileStreamTest, UseClosedStream) {
[email protected]50f91af2014-04-09 17:28:56161 int rv = 0;
162 TestCompletionCallback callback;
163 TestInt64CompletionCallback callback64;
164
skyostil4891b25b2015-06-11 11:43:45165 FileStream stream(base::ThreadTaskRunnerHandle::Get());
[email protected]21da6eb2008-11-03 17:18:14166
167 EXPECT_FALSE(stream.IsOpen());
168
169 // Try seeking...
[email protected]633ff3b12014-06-20 23:30:18170 rv = stream.Seek(base::File::FROM_BEGIN, 5, callback64.callback());
[email protected]50f91af2014-04-09 17:28:56171 EXPECT_EQ(ERR_UNEXPECTED, callback64.GetResult(rv));
[email protected]21da6eb2008-11-03 17:18:14172
173 // Try reading...
[email protected]50f91af2014-04-09 17:28:56174 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(10);
dchengc80fed2a2014-08-27 21:47:36175 rv = stream.Read(buf.get(), buf->size(), callback.callback());
[email protected]50f91af2014-04-09 17:28:56176 EXPECT_EQ(ERR_UNEXPECTED, callback.GetResult(rv));
[email protected]21da6eb2008-11-03 17:18:14177}
178
[email protected]633ff3b12014-06-20 23:30:18179TEST_F(FileStreamTest, Read) {
wtc69f8ea82015-06-04 00:08:13180 int64_t file_size;
[email protected]a08305912014-03-21 00:41:15181 EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
[email protected]21da6eb2008-11-03 17:18:14182
skyostil4891b25b2015-06-11 11:43:45183 FileStream stream(base::ThreadTaskRunnerHandle::Get());
[email protected]a08305912014-03-21 00:41:15184 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
185 base::File::FLAG_ASYNC;
[email protected]66af1d62013-03-06 23:13:20186 TestCompletionCallback callback;
187 int rv = stream.Open(temp_file_path(), flags, callback.callback());
[email protected]633ff3b12014-06-20 23:30:18188 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]21da6eb2008-11-03 17:18:14189
[email protected]4c2048a2009-03-24 21:02:01190 int total_bytes_read = 0;
[email protected]21da6eb2008-11-03 17:18:14191
192 std::string data_read;
193 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20194 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
[email protected]90499482013-06-01 00:39:50195 rv = stream.Read(buf.get(), buf->size(), callback.callback());
[email protected]633ff3b12014-06-20 23:30:18196 rv = callback.GetResult(rv);
[email protected]21da6eb2008-11-03 17:18:14197 EXPECT_LE(0, rv);
198 if (rv <= 0)
199 break;
200 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20201 data_read.append(buf->data(), rv);
[email protected]21da6eb2008-11-03 17:18:14202 }
203 EXPECT_EQ(file_size, total_bytes_read);
[email protected]4c2048a2009-03-24 21:02:01204 EXPECT_EQ(kTestData, data_read);
205}
206
[email protected]633ff3b12014-06-20 23:30:18207TEST_F(FileStreamTest, Read_EarlyDelete) {
wtc69f8ea82015-06-04 00:08:13208 int64_t file_size;
[email protected]a08305912014-03-21 00:41:15209 EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
[email protected]06b802b2012-02-22 03:34:54210
[email protected]dd2c4382013-09-07 16:01:47211 scoped_ptr<FileStream> stream(
skyostil4891b25b2015-06-11 11:43:45212 new FileStream(base::ThreadTaskRunnerHandle::Get()));
[email protected]a08305912014-03-21 00:41:15213 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
214 base::File::FLAG_ASYNC;
[email protected]06b802b2012-02-22 03:34:54215 TestCompletionCallback callback;
216 int rv = stream->Open(temp_file_path(), flags, callback.callback());
217 EXPECT_EQ(ERR_IO_PENDING, rv);
218 EXPECT_EQ(OK, callback.WaitForResult());
219
[email protected]06b802b2012-02-22 03:34:54220 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
[email protected]90499482013-06-01 00:39:50221 rv = stream->Read(buf.get(), buf->size(), callback.callback());
[email protected]06b802b2012-02-22 03:34:54222 stream.reset(); // Delete instead of closing it.
223 if (rv < 0) {
224 EXPECT_EQ(ERR_IO_PENDING, rv);
225 // The callback should not be called if the request is cancelled.
[email protected]dd2c4382013-09-07 16:01:47226 base::RunLoop().RunUntilIdle();
[email protected]06b802b2012-02-22 03:34:54227 EXPECT_FALSE(callback.have_result());
228 } else {
229 EXPECT_EQ(std::string(kTestData, rv), std::string(buf->data(), rv));
230 }
231}
232
[email protected]633ff3b12014-06-20 23:30:18233TEST_F(FileStreamTest, Read_FromOffset) {
wtc69f8ea82015-06-04 00:08:13234 int64_t file_size;
[email protected]a08305912014-03-21 00:41:15235 EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
[email protected]21da6eb2008-11-03 17:18:14236
skyostil4891b25b2015-06-11 11:43:45237 FileStream stream(base::ThreadTaskRunnerHandle::Get());
[email protected]a08305912014-03-21 00:41:15238 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
239 base::File::FLAG_ASYNC;
[email protected]66af1d62013-03-06 23:13:20240 TestCompletionCallback callback;
241 int rv = stream.Open(temp_file_path(), flags, callback.callback());
242 EXPECT_EQ(ERR_IO_PENDING, rv);
243 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]21da6eb2008-11-03 17:18:14244
[email protected]cf02541b2012-04-11 08:02:17245 TestInt64CompletionCallback callback64;
wtc69f8ea82015-06-04 00:08:13246 const int64_t kOffset = 3;
[email protected]633ff3b12014-06-20 23:30:18247 rv = stream.Seek(base::File::FROM_BEGIN, kOffset, callback64.callback());
[email protected]cf02541b2012-04-11 08:02:17248 ASSERT_EQ(ERR_IO_PENDING, rv);
wtc69f8ea82015-06-04 00:08:13249 int64_t new_offset = callback64.WaitForResult();
[email protected]21da6eb2008-11-03 17:18:14250 EXPECT_EQ(kOffset, new_offset);
251
[email protected]4c2048a2009-03-24 21:02:01252 int total_bytes_read = 0;
[email protected]21da6eb2008-11-03 17:18:14253
254 std::string data_read;
255 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20256 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
[email protected]90499482013-06-01 00:39:50257 rv = stream.Read(buf.get(), buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07258 if (rv == ERR_IO_PENDING)
[email protected]21da6eb2008-11-03 17:18:14259 rv = callback.WaitForResult();
260 EXPECT_LE(0, rv);
261 if (rv <= 0)
262 break;
263 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20264 data_read.append(buf->data(), rv);
[email protected]21da6eb2008-11-03 17:18:14265 }
266 EXPECT_EQ(file_size - kOffset, total_bytes_read);
[email protected]4c2048a2009-03-24 21:02:01267 EXPECT_EQ(kTestData + kOffset, data_read);
[email protected]21da6eb2008-11-03 17:18:14268}
269
[email protected]633ff3b12014-06-20 23:30:18270TEST_F(FileStreamTest, SeekAround) {
skyostil4891b25b2015-06-11 11:43:45271 FileStream stream(base::ThreadTaskRunnerHandle::Get());
[email protected]a08305912014-03-21 00:41:15272 int flags = base::File::FLAG_OPEN | base::File::FLAG_ASYNC |
273 base::File::FLAG_READ;
[email protected]66af1d62013-03-06 23:13:20274 TestCompletionCallback callback;
275 int rv = stream.Open(temp_file_path(), flags, callback.callback());
276 EXPECT_EQ(ERR_IO_PENDING, rv);
277 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]cf02541b2012-04-11 08:02:17278
[email protected]66af1d62013-03-06 23:13:20279 TestInt64CompletionCallback callback64;
[email protected]cf02541b2012-04-11 08:02:17280
wtc69f8ea82015-06-04 00:08:13281 const int64_t kOffset = 3;
[email protected]633ff3b12014-06-20 23:30:18282 rv = stream.Seek(base::File::FROM_BEGIN, kOffset, callback64.callback());
[email protected]cf02541b2012-04-11 08:02:17283 ASSERT_EQ(ERR_IO_PENDING, rv);
wtc69f8ea82015-06-04 00:08:13284 int64_t new_offset = callback64.WaitForResult();
[email protected]cf02541b2012-04-11 08:02:17285 EXPECT_EQ(kOffset, new_offset);
286
[email protected]633ff3b12014-06-20 23:30:18287 rv = stream.Seek(base::File::FROM_CURRENT, kOffset, callback64.callback());
[email protected]cf02541b2012-04-11 08:02:17288 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]66af1d62013-03-06 23:13:20289 new_offset = callback64.WaitForResult();
[email protected]cf02541b2012-04-11 08:02:17290 EXPECT_EQ(2 * kOffset, new_offset);
291
[email protected]633ff3b12014-06-20 23:30:18292 rv = stream.Seek(base::File::FROM_CURRENT, -kOffset, callback64.callback());
[email protected]cf02541b2012-04-11 08:02:17293 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]66af1d62013-03-06 23:13:20294 new_offset = callback64.WaitForResult();
[email protected]cf02541b2012-04-11 08:02:17295 EXPECT_EQ(kOffset, new_offset);
296
297 const int kTestDataLen = arraysize(kTestData) - 1;
298
[email protected]633ff3b12014-06-20 23:30:18299 rv = stream.Seek(base::File::FROM_END, -kTestDataLen, callback64.callback());
[email protected]cf02541b2012-04-11 08:02:17300 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]66af1d62013-03-06 23:13:20301 new_offset = callback64.WaitForResult();
[email protected]21da6eb2008-11-03 17:18:14302 EXPECT_EQ(0, new_offset);
303}
304
[email protected]633ff3b12014-06-20 23:30:18305TEST_F(FileStreamTest, Write) {
skyostil4891b25b2015-06-11 11:43:45306 FileStream stream(base::ThreadTaskRunnerHandle::Get());
[email protected]a08305912014-03-21 00:41:15307 int flags = base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
308 base::File::FLAG_ASYNC;
[email protected]66af1d62013-03-06 23:13:20309 TestCompletionCallback callback;
310 int rv = stream.Open(temp_file_path(), flags, callback.callback());
[email protected]633ff3b12014-06-20 23:30:18311 EXPECT_EQ(OK, callback.GetResult(rv));
[email protected]21da6eb2008-11-03 17:18:14312
wtc69f8ea82015-06-04 00:08:13313 int64_t file_size;
[email protected]a08305912014-03-21 00:41:15314 EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
[email protected]21da6eb2008-11-03 17:18:14315 EXPECT_EQ(0, file_size);
316
[email protected]633ff3b12014-06-20 23:30:18317 scoped_refptr<IOBuffer> buf = CreateTestDataBuffer();
318 rv = stream.Write(buf.get(), kTestDataSize, callback.callback());
319 rv = callback.GetResult(rv);
320 EXPECT_EQ(kTestDataSize, rv);
[email protected]21da6eb2008-11-03 17:18:14321
[email protected]a08305912014-03-21 00:41:15322 EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
[email protected]633ff3b12014-06-20 23:30:18323 EXPECT_EQ(kTestDataSize, file_size);
324
325 std::string data_read;
326 EXPECT_TRUE(base::ReadFileToString(temp_file_path(), &data_read));
327 EXPECT_EQ(kTestData, data_read);
[email protected]21da6eb2008-11-03 17:18:14328}
329
[email protected]633ff3b12014-06-20 23:30:18330TEST_F(FileStreamTest, Write_EarlyDelete) {
[email protected]dd2c4382013-09-07 16:01:47331 scoped_ptr<FileStream> stream(
skyostil4891b25b2015-06-11 11:43:45332 new FileStream(base::ThreadTaskRunnerHandle::Get()));
[email protected]a08305912014-03-21 00:41:15333 int flags = base::File::FLAG_CREATE_ALWAYS | base::File::FLAG_WRITE |
334 base::File::FLAG_ASYNC;
[email protected]66af1d62013-03-06 23:13:20335 TestCompletionCallback callback;
336 int rv = stream->Open(temp_file_path(), flags, callback.callback());
337 EXPECT_EQ(ERR_IO_PENDING, rv);
338 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]4c2048a2009-03-24 21:02:01339
wtc69f8ea82015-06-04 00:08:13340 int64_t file_size;
[email protected]a08305912014-03-21 00:41:15341 EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
[email protected]4c2048a2009-03-24 21:02:01342 EXPECT_EQ(0, file_size);
343
[email protected]9f49afb2012-02-16 09:59:20344 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
[email protected]90499482013-06-01 00:39:50345 rv = stream->Write(buf.get(), buf->size(), callback.callback());
[email protected]aab1b9e2012-11-06 00:29:51346 stream.reset();
[email protected]3828a752009-06-03 23:05:59347 if (rv < 0) {
[email protected]8effd3f62011-03-25 16:29:07348 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3828a752009-06-03 23:05:59349 // The callback should not be called if the request is cancelled.
[email protected]dd2c4382013-09-07 16:01:47350 base::RunLoop().RunUntilIdle();
[email protected]3828a752009-06-03 23:05:59351 EXPECT_FALSE(callback.have_result());
352 } else {
[email protected]a08305912014-03-21 00:41:15353 EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
[email protected]3828a752009-06-03 23:05:59354 EXPECT_EQ(file_size, rv);
355 }
[email protected]4c2048a2009-03-24 21:02:01356}
357
[email protected]633ff3b12014-06-20 23:30:18358TEST_F(FileStreamTest, Write_FromOffset) {
wtc69f8ea82015-06-04 00:08:13359 int64_t file_size;
[email protected]a08305912014-03-21 00:41:15360 EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
[email protected]21da6eb2008-11-03 17:18:14361
skyostil4891b25b2015-06-11 11:43:45362 FileStream stream(base::ThreadTaskRunnerHandle::Get());
[email protected]a08305912014-03-21 00:41:15363 int flags = base::File::FLAG_OPEN | base::File::FLAG_WRITE |
364 base::File::FLAG_ASYNC;
[email protected]66af1d62013-03-06 23:13:20365 TestCompletionCallback callback;
366 int rv = stream.Open(temp_file_path(), flags, callback.callback());
367 EXPECT_EQ(ERR_IO_PENDING, rv);
368 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]21da6eb2008-11-03 17:18:14369
[email protected]cf02541b2012-04-11 08:02:17370 TestInt64CompletionCallback callback64;
wtc69f8ea82015-06-04 00:08:13371 const int64_t kOffset = 0;
[email protected]633ff3b12014-06-20 23:30:18372 rv = stream.Seek(base::File::FROM_END, kOffset, callback64.callback());
[email protected]cf02541b2012-04-11 08:02:17373 ASSERT_EQ(ERR_IO_PENDING, rv);
wtc69f8ea82015-06-04 00:08:13374 int64_t new_offset = callback64.WaitForResult();
[email protected]21da6eb2008-11-03 17:18:14375 EXPECT_EQ(kTestDataSize, new_offset);
376
[email protected]4c2048a2009-03-24 21:02:01377 int total_bytes_written = 0;
[email protected]21da6eb2008-11-03 17:18:14378
[email protected]9f49afb2012-02-16 09:59:20379 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
380 scoped_refptr<DrainableIOBuffer> drainable =
[email protected]90499482013-06-01 00:39:50381 new DrainableIOBuffer(buf.get(), buf->size());
[email protected]21da6eb2008-11-03 17:18:14382 while (total_bytes_written != kTestDataSize) {
[email protected]a08305912014-03-21 00:41:15383 rv = stream.Write(drainable.get(), drainable->BytesRemaining(),
384 callback.callback());
[email protected]8effd3f62011-03-25 16:29:07385 if (rv == ERR_IO_PENDING)
[email protected]21da6eb2008-11-03 17:18:14386 rv = callback.WaitForResult();
387 EXPECT_LT(0, rv);
388 if (rv <= 0)
389 break;
[email protected]9f49afb2012-02-16 09:59:20390 drainable->DidConsume(rv);
[email protected]21da6eb2008-11-03 17:18:14391 total_bytes_written += rv;
392 }
[email protected]a08305912014-03-21 00:41:15393 EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
[email protected]21da6eb2008-11-03 17:18:14394 EXPECT_EQ(file_size, kTestDataSize * 2);
395}
396
[email protected]633ff3b12014-06-20 23:30:18397TEST_F(FileStreamTest, BasicReadWrite) {
wtc69f8ea82015-06-04 00:08:13398 int64_t file_size;
[email protected]a08305912014-03-21 00:41:15399 EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
[email protected]4c2048a2009-03-24 21:02:01400
[email protected]dd2c4382013-09-07 16:01:47401 scoped_ptr<FileStream> stream(
skyostil4891b25b2015-06-11 11:43:45402 new FileStream(base::ThreadTaskRunnerHandle::Get()));
[email protected]a08305912014-03-21 00:41:15403 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
404 base::File::FLAG_WRITE | base::File::FLAG_ASYNC;
[email protected]66af1d62013-03-06 23:13:20405 TestCompletionCallback callback;
406 int rv = stream->Open(temp_file_path(), flags, callback.callback());
407 EXPECT_EQ(ERR_IO_PENDING, rv);
408 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]4c2048a2009-03-24 21:02:01409
wtc69f8ea82015-06-04 00:08:13410 int64_t total_bytes_read = 0;
[email protected]4c2048a2009-03-24 21:02:01411
412 std::string data_read;
413 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20414 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
[email protected]90499482013-06-01 00:39:50415 rv = stream->Read(buf.get(), buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07416 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01417 rv = callback.WaitForResult();
418 EXPECT_LE(0, rv);
419 if (rv <= 0)
420 break;
421 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20422 data_read.append(buf->data(), rv);
[email protected]4c2048a2009-03-24 21:02:01423 }
424 EXPECT_EQ(file_size, total_bytes_read);
425 EXPECT_TRUE(data_read == kTestData);
426
427 int total_bytes_written = 0;
428
[email protected]9f49afb2012-02-16 09:59:20429 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
430 scoped_refptr<DrainableIOBuffer> drainable =
[email protected]90499482013-06-01 00:39:50431 new DrainableIOBuffer(buf.get(), buf->size());
[email protected]4c2048a2009-03-24 21:02:01432 while (total_bytes_written != kTestDataSize) {
[email protected]a08305912014-03-21 00:41:15433 rv = stream->Write(drainable.get(), drainable->BytesRemaining(),
434 callback.callback());
[email protected]8effd3f62011-03-25 16:29:07435 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01436 rv = callback.WaitForResult();
437 EXPECT_LT(0, rv);
438 if (rv <= 0)
439 break;
[email protected]9f49afb2012-02-16 09:59:20440 drainable->DidConsume(rv);
[email protected]4c2048a2009-03-24 21:02:01441 total_bytes_written += rv;
442 }
443
[email protected]aab1b9e2012-11-06 00:29:51444 stream.reset();
[email protected]4c2048a2009-03-24 21:02:01445
[email protected]a08305912014-03-21 00:41:15446 EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
[email protected]4c2048a2009-03-24 21:02:01447 EXPECT_EQ(kTestDataSize * 2, file_size);
448}
449
[email protected]633ff3b12014-06-20 23:30:18450TEST_F(FileStreamTest, BasicWriteRead) {
wtc69f8ea82015-06-04 00:08:13451 int64_t file_size;
[email protected]a08305912014-03-21 00:41:15452 EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
[email protected]4c2048a2009-03-24 21:02:01453
[email protected]dd2c4382013-09-07 16:01:47454 scoped_ptr<FileStream> stream(
skyostil4891b25b2015-06-11 11:43:45455 new FileStream(base::ThreadTaskRunnerHandle::Get()));
[email protected]a08305912014-03-21 00:41:15456 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
457 base::File::FLAG_WRITE | base::File::FLAG_ASYNC;
[email protected]66af1d62013-03-06 23:13:20458 TestCompletionCallback callback;
459 int rv = stream->Open(temp_file_path(), flags, callback.callback());
460 EXPECT_EQ(ERR_IO_PENDING, rv);
461 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]4c2048a2009-03-24 21:02:01462
[email protected]cf02541b2012-04-11 08:02:17463 TestInt64CompletionCallback callback64;
[email protected]633ff3b12014-06-20 23:30:18464 rv = stream->Seek(base::File::FROM_END, 0, callback64.callback());
[email protected]cf02541b2012-04-11 08:02:17465 ASSERT_EQ(ERR_IO_PENDING, rv);
wtc69f8ea82015-06-04 00:08:13466 int64_t offset = callback64.WaitForResult();
[email protected]4c2048a2009-03-24 21:02:01467 EXPECT_EQ(offset, file_size);
468
[email protected]4c2048a2009-03-24 21:02:01469 int total_bytes_written = 0;
470
[email protected]9f49afb2012-02-16 09:59:20471 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
472 scoped_refptr<DrainableIOBuffer> drainable =
[email protected]90499482013-06-01 00:39:50473 new DrainableIOBuffer(buf.get(), buf->size());
[email protected]4c2048a2009-03-24 21:02:01474 while (total_bytes_written != kTestDataSize) {
[email protected]a08305912014-03-21 00:41:15475 rv = stream->Write(drainable.get(), drainable->BytesRemaining(),
476 callback.callback());
[email protected]8effd3f62011-03-25 16:29:07477 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01478 rv = callback.WaitForResult();
479 EXPECT_LT(0, rv);
480 if (rv <= 0)
481 break;
[email protected]9f49afb2012-02-16 09:59:20482 drainable->DidConsume(rv);
[email protected]4c2048a2009-03-24 21:02:01483 total_bytes_written += rv;
484 }
485
486 EXPECT_EQ(kTestDataSize, total_bytes_written);
487
[email protected]633ff3b12014-06-20 23:30:18488 rv = stream->Seek(base::File::FROM_BEGIN, 0, callback64.callback());
[email protected]cf02541b2012-04-11 08:02:17489 ASSERT_EQ(ERR_IO_PENDING, rv);
490 offset = callback64.WaitForResult();
[email protected]4c2048a2009-03-24 21:02:01491 EXPECT_EQ(0, offset);
492
493 int total_bytes_read = 0;
494
495 std::string data_read;
496 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20497 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
[email protected]90499482013-06-01 00:39:50498 rv = stream->Read(buf.get(), buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07499 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01500 rv = callback.WaitForResult();
501 EXPECT_LE(0, rv);
502 if (rv <= 0)
503 break;
504 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20505 data_read.append(buf->data(), rv);
[email protected]4c2048a2009-03-24 21:02:01506 }
[email protected]aab1b9e2012-11-06 00:29:51507 stream.reset();
[email protected]4c2048a2009-03-24 21:02:01508
[email protected]a08305912014-03-21 00:41:15509 EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
[email protected]4c2048a2009-03-24 21:02:01510 EXPECT_EQ(kTestDataSize * 2, file_size);
511
512 EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
513 const std::string kExpectedFileData =
514 std::string(kTestData) + std::string(kTestData);
515 EXPECT_EQ(kExpectedFileData, data_read);
516}
517
[email protected]5eb431e22011-10-12 08:51:38518class TestWriteReadCompletionCallback {
[email protected]4c2048a2009-03-24 21:02:01519 public:
[email protected]90499482013-06-01 00:39:50520 TestWriteReadCompletionCallback(FileStream* stream,
521 int* total_bytes_written,
522 int* total_bytes_read,
523 std::string* data_read)
[email protected]4c2048a2009-03-24 21:02:01524 : result_(0),
525 have_result_(false),
526 waiting_for_result_(false),
527 stream_(stream),
528 total_bytes_written_(total_bytes_written),
529 total_bytes_read_(total_bytes_read),
[email protected]5eb431e22011-10-12 08:51:38530 data_read_(data_read),
531 callback_(base::Bind(&TestWriteReadCompletionCallback::OnComplete,
[email protected]9f49afb2012-02-16 09:59:20532 base::Unretained(this))),
533 test_data_(CreateTestDataBuffer()),
[email protected]90499482013-06-01 00:39:50534 drainable_(new DrainableIOBuffer(test_data_.get(), kTestDataSize)) {}
[email protected]4c2048a2009-03-24 21:02:01535
536 int WaitForResult() {
537 DCHECK(!waiting_for_result_);
538 while (!have_result_) {
539 waiting_for_result_ = true;
[email protected]dd2c4382013-09-07 16:01:47540 base::RunLoop().Run();
[email protected]4c2048a2009-03-24 21:02:01541 waiting_for_result_ = false;
542 }
543 have_result_ = false; // auto-reset for next callback
544 return result_;
545 }
546
[email protected]5eb431e22011-10-12 08:51:38547 const CompletionCallback& callback() const { return callback_; }
548
ananta959eaea2015-02-03 19:50:50549 void ValidateWrittenData() {
550 TestCompletionCallback callback;
551 int rv = 0;
552 for (;;) {
553 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
554 rv = stream_->Read(buf.get(), buf->size(), callback.callback());
555 if (rv == ERR_IO_PENDING) {
556 base::MessageLoop::ScopedNestableTaskAllower allow(
557 base::MessageLoop::current());
558 rv = callback.WaitForResult();
559 }
560 EXPECT_LE(0, rv);
561 if (rv <= 0)
562 break;
563 *total_bytes_read_ += rv;
564 data_read_->append(buf->data(), rv);
565 }
566 }
567
[email protected]4c2048a2009-03-24 21:02:01568 private:
[email protected]5eb431e22011-10-12 08:51:38569 void OnComplete(int result) {
570 DCHECK_LT(0, result);
571 *total_bytes_written_ += result;
[email protected]4c2048a2009-03-24 21:02:01572
573 int rv;
574
575 if (*total_bytes_written_ != kTestDataSize) {
576 // Recurse to finish writing all data.
577 int total_bytes_written = 0, total_bytes_read = 0;
578 std::string data_read;
[email protected]5eb431e22011-10-12 08:51:38579 TestWriteReadCompletionCallback callback(
[email protected]4c2048a2009-03-24 21:02:01580 stream_, &total_bytes_written, &total_bytes_read, &data_read);
[email protected]90499482013-06-01 00:39:50581 rv = stream_->Write(
582 drainable_.get(), drainable_->BytesRemaining(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07583 DCHECK_EQ(ERR_IO_PENDING, rv);
[email protected]4c2048a2009-03-24 21:02:01584 rv = callback.WaitForResult();
[email protected]9f49afb2012-02-16 09:59:20585 drainable_->DidConsume(total_bytes_written);
[email protected]4c2048a2009-03-24 21:02:01586 *total_bytes_written_ += total_bytes_written;
587 *total_bytes_read_ += total_bytes_read;
588 *data_read_ += data_read;
589 } else { // We're done writing all data. Start reading the data.
[email protected]50f91af2014-04-09 17:28:56590 TestInt64CompletionCallback callback64;
591 EXPECT_EQ(ERR_IO_PENDING,
[email protected]633ff3b12014-06-20 23:30:18592 stream_->Seek(base::File::FROM_BEGIN, 0,
593 callback64.callback()));
[email protected]50f91af2014-04-09 17:28:56594 {
595 base::MessageLoop::ScopedNestableTaskAllower allow(
596 base::MessageLoop::current());
597 EXPECT_LE(0, callback64.WaitForResult());
598 }
[email protected]4c2048a2009-03-24 21:02:01599 }
600
601 result_ = *total_bytes_written_;
602 have_result_ = true;
603 if (waiting_for_result_)
[email protected]2da659e2013-05-23 20:51:34604 base::MessageLoop::current()->Quit();
[email protected]4c2048a2009-03-24 21:02:01605 }
606
607 int result_;
608 bool have_result_;
609 bool waiting_for_result_;
[email protected]8effd3f62011-03-25 16:29:07610 FileStream* stream_;
[email protected]4c2048a2009-03-24 21:02:01611 int* total_bytes_written_;
612 int* total_bytes_read_;
613 std::string* data_read_;
[email protected]5eb431e22011-10-12 08:51:38614 const CompletionCallback callback_;
[email protected]9f49afb2012-02-16 09:59:20615 scoped_refptr<IOBufferWithSize> test_data_;
616 scoped_refptr<DrainableIOBuffer> drainable_;
[email protected]4c2048a2009-03-24 21:02:01617
[email protected]5eb431e22011-10-12 08:51:38618 DISALLOW_COPY_AND_ASSIGN(TestWriteReadCompletionCallback);
[email protected]4c2048a2009-03-24 21:02:01619};
620
[email protected]633ff3b12014-06-20 23:30:18621TEST_F(FileStreamTest, WriteRead) {
wtc69f8ea82015-06-04 00:08:13622 int64_t file_size;
[email protected]a08305912014-03-21 00:41:15623 EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
[email protected]4c2048a2009-03-24 21:02:01624
[email protected]dd2c4382013-09-07 16:01:47625 scoped_ptr<FileStream> stream(
skyostil4891b25b2015-06-11 11:43:45626 new FileStream(base::ThreadTaskRunnerHandle::Get()));
[email protected]a08305912014-03-21 00:41:15627 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
628 base::File::FLAG_WRITE | base::File::FLAG_ASYNC;
[email protected]66af1d62013-03-06 23:13:20629 TestCompletionCallback open_callback;
630 int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
631 EXPECT_EQ(ERR_IO_PENDING, rv);
632 EXPECT_EQ(OK, open_callback.WaitForResult());
[email protected]4c2048a2009-03-24 21:02:01633
[email protected]50f91af2014-04-09 17:28:56634 TestInt64CompletionCallback callback64;
[email protected]633ff3b12014-06-20 23:30:18635 EXPECT_EQ(ERR_IO_PENDING,
636 stream->Seek(base::File::FROM_END, 0, callback64.callback()));
[email protected]50f91af2014-04-09 17:28:56637 EXPECT_EQ(file_size, callback64.WaitForResult());
[email protected]4c2048a2009-03-24 21:02:01638
639 int total_bytes_written = 0;
640 int total_bytes_read = 0;
641 std::string data_read;
[email protected]aab1b9e2012-11-06 00:29:51642 TestWriteReadCompletionCallback callback(stream.get(), &total_bytes_written,
[email protected]4c2048a2009-03-24 21:02:01643 &total_bytes_read, &data_read);
644
[email protected]9f49afb2012-02-16 09:59:20645 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
[email protected]90499482013-06-01 00:39:50646 rv = stream->Write(buf.get(), buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07647 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01648 rv = callback.WaitForResult();
649 EXPECT_LT(0, rv);
650 EXPECT_EQ(kTestDataSize, total_bytes_written);
651
ananta959eaea2015-02-03 19:50:50652 callback.ValidateWrittenData();
653
[email protected]aab1b9e2012-11-06 00:29:51654 stream.reset();
[email protected]4c2048a2009-03-24 21:02:01655
[email protected]a08305912014-03-21 00:41:15656 EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
[email protected]4c2048a2009-03-24 21:02:01657 EXPECT_EQ(kTestDataSize * 2, file_size);
658
659 EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
660 const std::string kExpectedFileData =
661 std::string(kTestData) + std::string(kTestData);
662 EXPECT_EQ(kExpectedFileData, data_read);
663}
664
[email protected]5eb431e22011-10-12 08:51:38665class TestWriteCloseCompletionCallback {
[email protected]4c2048a2009-03-24 21:02:01666 public:
[email protected]5eb431e22011-10-12 08:51:38667 TestWriteCloseCompletionCallback(FileStream* stream, int* total_bytes_written)
[email protected]4c2048a2009-03-24 21:02:01668 : result_(0),
669 have_result_(false),
670 waiting_for_result_(false),
671 stream_(stream),
[email protected]5eb431e22011-10-12 08:51:38672 total_bytes_written_(total_bytes_written),
673 callback_(base::Bind(&TestWriteCloseCompletionCallback::OnComplete,
[email protected]9f49afb2012-02-16 09:59:20674 base::Unretained(this))),
675 test_data_(CreateTestDataBuffer()),
[email protected]90499482013-06-01 00:39:50676 drainable_(new DrainableIOBuffer(test_data_.get(), kTestDataSize)) {}
[email protected]4c2048a2009-03-24 21:02:01677
678 int WaitForResult() {
679 DCHECK(!waiting_for_result_);
680 while (!have_result_) {
681 waiting_for_result_ = true;
[email protected]dd2c4382013-09-07 16:01:47682 base::RunLoop().Run();
[email protected]4c2048a2009-03-24 21:02:01683 waiting_for_result_ = false;
684 }
685 have_result_ = false; // auto-reset for next callback
686 return result_;
687 }
688
[email protected]5eb431e22011-10-12 08:51:38689 const CompletionCallback& callback() const { return callback_; }
690
[email protected]4c2048a2009-03-24 21:02:01691 private:
[email protected]5eb431e22011-10-12 08:51:38692 void OnComplete(int result) {
693 DCHECK_LT(0, result);
694 *total_bytes_written_ += result;
[email protected]4c2048a2009-03-24 21:02:01695
696 int rv;
697
698 if (*total_bytes_written_ != kTestDataSize) {
699 // Recurse to finish writing all data.
700 int total_bytes_written = 0;
[email protected]5eb431e22011-10-12 08:51:38701 TestWriteCloseCompletionCallback callback(stream_, &total_bytes_written);
[email protected]90499482013-06-01 00:39:50702 rv = stream_->Write(
703 drainable_.get(), drainable_->BytesRemaining(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07704 DCHECK_EQ(ERR_IO_PENDING, rv);
[email protected]4c2048a2009-03-24 21:02:01705 rv = callback.WaitForResult();
[email protected]9f49afb2012-02-16 09:59:20706 drainable_->DidConsume(total_bytes_written);
[email protected]4c2048a2009-03-24 21:02:01707 *total_bytes_written_ += total_bytes_written;
[email protected]4c2048a2009-03-24 21:02:01708 }
709
710 result_ = *total_bytes_written_;
711 have_result_ = true;
712 if (waiting_for_result_)
[email protected]2da659e2013-05-23 20:51:34713 base::MessageLoop::current()->Quit();
[email protected]4c2048a2009-03-24 21:02:01714 }
715
716 int result_;
717 bool have_result_;
718 bool waiting_for_result_;
[email protected]8effd3f62011-03-25 16:29:07719 FileStream* stream_;
[email protected]4c2048a2009-03-24 21:02:01720 int* total_bytes_written_;
[email protected]5eb431e22011-10-12 08:51:38721 const CompletionCallback callback_;
[email protected]9f49afb2012-02-16 09:59:20722 scoped_refptr<IOBufferWithSize> test_data_;
723 scoped_refptr<DrainableIOBuffer> drainable_;
[email protected]4c2048a2009-03-24 21:02:01724
[email protected]5eb431e22011-10-12 08:51:38725 DISALLOW_COPY_AND_ASSIGN(TestWriteCloseCompletionCallback);
[email protected]4c2048a2009-03-24 21:02:01726};
727
[email protected]633ff3b12014-06-20 23:30:18728TEST_F(FileStreamTest, WriteClose) {
wtc69f8ea82015-06-04 00:08:13729 int64_t file_size;
[email protected]a08305912014-03-21 00:41:15730 EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
[email protected]4c2048a2009-03-24 21:02:01731
[email protected]dd2c4382013-09-07 16:01:47732 scoped_ptr<FileStream> stream(
skyostil4891b25b2015-06-11 11:43:45733 new FileStream(base::ThreadTaskRunnerHandle::Get()));
[email protected]a08305912014-03-21 00:41:15734 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
735 base::File::FLAG_WRITE | base::File::FLAG_ASYNC;
[email protected]66af1d62013-03-06 23:13:20736 TestCompletionCallback open_callback;
737 int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
738 EXPECT_EQ(ERR_IO_PENDING, rv);
739 EXPECT_EQ(OK, open_callback.WaitForResult());
[email protected]4c2048a2009-03-24 21:02:01740
[email protected]50f91af2014-04-09 17:28:56741 TestInt64CompletionCallback callback64;
[email protected]633ff3b12014-06-20 23:30:18742 EXPECT_EQ(ERR_IO_PENDING,
743 stream->Seek(base::File::FROM_END, 0, callback64.callback()));
[email protected]50f91af2014-04-09 17:28:56744 EXPECT_EQ(file_size, callback64.WaitForResult());
[email protected]4c2048a2009-03-24 21:02:01745
746 int total_bytes_written = 0;
[email protected]aab1b9e2012-11-06 00:29:51747 TestWriteCloseCompletionCallback callback(stream.get(), &total_bytes_written);
[email protected]4c2048a2009-03-24 21:02:01748
[email protected]9f49afb2012-02-16 09:59:20749 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
[email protected]90499482013-06-01 00:39:50750 rv = stream->Write(buf.get(), buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07751 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01752 total_bytes_written = callback.WaitForResult();
753 EXPECT_LT(0, total_bytes_written);
754 EXPECT_EQ(kTestDataSize, total_bytes_written);
755
[email protected]aab1b9e2012-11-06 00:29:51756 stream.reset();
757
[email protected]a08305912014-03-21 00:41:15758 EXPECT_TRUE(base::GetFileSize(temp_file_path(), &file_size));
[email protected]4c2048a2009-03-24 21:02:01759 EXPECT_EQ(kTestDataSize * 2, file_size);
760}
761
[email protected]633ff3b12014-06-20 23:30:18762TEST_F(FileStreamTest, OpenAndDelete) {
[email protected]e3ec0625d2014-05-02 23:58:54763 scoped_refptr<base::SequencedWorkerPool> pool(
764 new base::SequencedWorkerPool(1, "StreamTest"));
765
766 bool prev = base::ThreadRestrictions::SetIOAllowed(false);
767 scoped_ptr<FileStream> stream(new FileStream(pool.get()));
[email protected]a08305912014-03-21 00:41:15768 int flags = base::File::FLAG_OPEN | base::File::FLAG_WRITE |
769 base::File::FLAG_ASYNC;
[email protected]dbb747c2012-02-29 19:29:47770 TestCompletionCallback open_callback;
771 int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
772 EXPECT_EQ(ERR_IO_PENDING, rv);
773
774 // Delete the stream without waiting for the open operation to be
775 // complete. Should be safe.
776 stream.reset();
[email protected]e3ec0625d2014-05-02 23:58:54777
778 // Force an operation through the pool.
779 scoped_ptr<FileStream> stream2(new FileStream(pool.get()));
780 TestCompletionCallback open_callback2;
781 rv = stream2->Open(temp_file_path(), flags, open_callback2.callback());
782 EXPECT_EQ(OK, open_callback2.GetResult(rv));
783 stream2.reset();
784
785 pool->Shutdown();
786
[email protected]dbb747c2012-02-29 19:29:47787 // open_callback won't be called.
[email protected]dd2c4382013-09-07 16:01:47788 base::RunLoop().RunUntilIdle();
[email protected]dbb747c2012-02-29 19:29:47789 EXPECT_FALSE(open_callback.have_result());
[email protected]e3ec0625d2014-05-02 23:58:54790 base::ThreadRestrictions::SetIOAllowed(prev);
[email protected]dbb747c2012-02-29 19:29:47791}
792
[email protected]633ff3b12014-06-20 23:30:18793// Verify that Write() errors are mapped correctly.
794TEST_F(FileStreamTest, WriteError) {
[email protected]7f00ad62013-09-14 00:56:21795 // Try opening file as read-only and then writing to it using FileStream.
wtc69f8ea82015-06-04 00:08:13796 uint32_t flags =
797 base::File::FLAG_OPEN | base::File::FLAG_READ | base::File::FLAG_ASYNC;
[email protected]bfb88ec2013-02-27 20:21:35798
[email protected]a08305912014-03-21 00:41:15799 base::File file(temp_file_path(), flags);
800 ASSERT_TRUE(file.IsValid());
801
[email protected]7f00ad62013-09-14 00:56:21802 scoped_ptr<FileStream> stream(
skyostil4891b25b2015-06-11 11:43:45803 new FileStream(file.Pass(), base::ThreadTaskRunnerHandle::Get()));
[email protected]7f00ad62013-09-14 00:56:21804
805 scoped_refptr<IOBuffer> buf = new IOBuffer(1);
[email protected]1a00d082013-09-14 19:57:16806 buf->data()[0] = 0;
807
[email protected]7f00ad62013-09-14 00:56:21808 TestCompletionCallback callback;
809 int rv = stream->Write(buf.get(), 1, callback.callback());
[email protected]bfb88ec2013-02-27 20:21:35810 if (rv == ERR_IO_PENDING)
811 rv = callback.WaitForResult();
812 EXPECT_LT(rv, 0);
[email protected]7f00ad62013-09-14 00:56:21813
[email protected]a08305912014-03-21 00:41:15814 stream.reset();
815 base::RunLoop().RunUntilIdle();
[email protected]bfb88ec2013-02-27 20:21:35816}
817
[email protected]633ff3b12014-06-20 23:30:18818// Verify that Read() errors are mapped correctly.
819TEST_F(FileStreamTest, ReadError) {
[email protected]7f00ad62013-09-14 00:56:21820 // Try opening file for write and then reading from it using FileStream.
wtc69f8ea82015-06-04 00:08:13821 uint32_t flags =
822 base::File::FLAG_OPEN | base::File::FLAG_WRITE | base::File::FLAG_ASYNC;
[email protected]bfb88ec2013-02-27 20:21:35823
[email protected]a08305912014-03-21 00:41:15824 base::File file(temp_file_path(), flags);
825 ASSERT_TRUE(file.IsValid());
826
[email protected]7f00ad62013-09-14 00:56:21827 scoped_ptr<FileStream> stream(
skyostil4891b25b2015-06-11 11:43:45828 new FileStream(file.Pass(), base::ThreadTaskRunnerHandle::Get()));
[email protected]7f00ad62013-09-14 00:56:21829
830 scoped_refptr<IOBuffer> buf = new IOBuffer(1);
831 TestCompletionCallback callback;
832 int rv = stream->Read(buf.get(), 1, callback.callback());
[email protected]bfb88ec2013-02-27 20:21:35833 if (rv == ERR_IO_PENDING)
834 rv = callback.WaitForResult();
835 EXPECT_LT(rv, 0);
[email protected]7f00ad62013-09-14 00:56:21836
[email protected]a08305912014-03-21 00:41:15837 stream.reset();
838 base::RunLoop().RunUntilIdle();
[email protected]bfb88ec2013-02-27 20:21:35839}
840
[email protected]f12d1e12013-11-20 07:04:55841#if defined(OS_ANDROID)
[email protected]633ff3b12014-06-20 23:30:18842TEST_F(FileStreamTest, ContentUriRead) {
[email protected]f12d1e12013-11-20 07:04:55843 base::FilePath test_dir;
844 PathService::Get(base::DIR_SOURCE_ROOT, &test_dir);
845 test_dir = test_dir.AppendASCII("net");
846 test_dir = test_dir.AppendASCII("data");
847 test_dir = test_dir.AppendASCII("file_stream_unittest");
848 ASSERT_TRUE(base::PathExists(test_dir));
849 base::FilePath image_file = test_dir.Append(FILE_PATH_LITERAL("red.png"));
850
851 // Insert the image into MediaStore. MediaStore will do some conversions, and
852 // return the content URI.
[email protected]92be8eb2014-08-07 22:57:11853 base::FilePath path = base::InsertImageIntoMediaStore(image_file);
[email protected]f12d1e12013-11-20 07:04:55854 EXPECT_TRUE(path.IsContentUri());
855 EXPECT_TRUE(base::PathExists(path));
wtc69f8ea82015-06-04 00:08:13856 int64_t file_size;
[email protected]56285702013-12-04 18:22:49857 EXPECT_TRUE(base::GetFileSize(path, &file_size));
[email protected]f12d1e12013-11-20 07:04:55858 EXPECT_LT(0, file_size);
859
skyostil4891b25b2015-06-11 11:43:45860 FileStream stream(base::ThreadTaskRunnerHandle::Get());
[email protected]a08305912014-03-21 00:41:15861 int flags = base::File::FLAG_OPEN | base::File::FLAG_READ |
862 base::File::FLAG_ASYNC;
[email protected]f12d1e12013-11-20 07:04:55863 TestCompletionCallback callback;
864 int rv = stream.Open(path, flags, callback.callback());
865 EXPECT_EQ(ERR_IO_PENDING, rv);
866 EXPECT_EQ(OK, callback.WaitForResult());
867
[email protected]f12d1e12013-11-20 07:04:55868 int total_bytes_read = 0;
869
870 std::string data_read;
871 for (;;) {
872 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
873 rv = stream.Read(buf.get(), buf->size(), callback.callback());
874 if (rv == ERR_IO_PENDING)
875 rv = callback.WaitForResult();
876 EXPECT_LE(0, rv);
877 if (rv <= 0)
878 break;
879 total_bytes_read += rv;
880 data_read.append(buf->data(), rv);
881 }
882 EXPECT_EQ(file_size, total_bytes_read);
883}
884#endif
885
[email protected]4c2048a2009-03-24 21:02:01886} // namespace
[email protected]96d73822011-10-10 02:11:24887
[email protected]8effd3f62011-03-25 16:29:07888} // namespace net