blob: 8eed06e0694c408e2b9eb1f65c450d0d1f06302f [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]21da6eb2008-11-03 17:18:149#include "base/file_util.h"
[email protected]5ee20982013-07-17 21:51:1810#include "base/message_loop/message_loop.h"
[email protected]dd2c4382013-09-07 16:01:4711#include "base/message_loop/message_loop_proxy.h"
[email protected]21da6eb2008-11-03 17:18:1412#include "base/path_service.h"
[email protected]92aad5222009-02-09 22:26:4113#include "base/platform_file.h"
[email protected]dd2c4382013-09-07 16:01:4714#include "base/run_loop.h"
[email protected]e3d66fde2012-02-17 22:10:3415#include "base/synchronization/waitable_event.h"
16#include "base/test/test_timeouts.h"
17#include "net/base/capturing_net_log.h"
[email protected]9f49afb2012-02-16 09:59:2018#include "net/base/io_buffer.h"
[email protected]21da6eb2008-11-03 17:18:1419#include "net/base/net_errors.h"
20#include "net/base/test_completion_callback.h"
21#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1522#include "testing/platform_test.h"
[email protected]21da6eb2008-11-03 17:18:1423
[email protected]8effd3f62011-03-25 16:29:0724namespace net {
[email protected]96d73822011-10-10 02:11:2425
[email protected]4c2048a2009-03-24 21:02:0126namespace {
27
28const char kTestData[] = "0123456789";
29const int kTestDataSize = arraysize(kTestData) - 1;
[email protected]21da6eb2008-11-03 17:18:1430
[email protected]9f49afb2012-02-16 09:59:2031// Creates an IOBufferWithSize that contains the kTestDataSize.
32IOBufferWithSize* CreateTestDataBuffer() {
33 IOBufferWithSize* buf = new IOBufferWithSize(kTestDataSize);
34 memcpy(buf->data(), kTestData, kTestDataSize);
35 return buf;
36}
37
[email protected]96d73822011-10-10 02:11:2438} // namespace
39
[email protected]21da6eb2008-11-03 17:18:1440class FileStreamTest : public PlatformTest {
41 public:
42 virtual void SetUp() {
43 PlatformTest::SetUp();
44
[email protected]33edeab2009-08-18 16:07:5545 file_util::CreateTemporaryFile(&temp_file_path_);
[email protected]7ff3f632009-10-13 18:43:3546 file_util::WriteFile(temp_file_path_, kTestData, kTestDataSize);
[email protected]21da6eb2008-11-03 17:18:1447 }
48 virtual void TearDown() {
[email protected]dd3aa792013-07-16 19:10:2349 EXPECT_TRUE(base::DeleteFile(temp_file_path_, false));
[email protected]21da6eb2008-11-03 17:18:1450
[email protected]dd2c4382013-09-07 16:01:4751 // FileStreamContexts must be asynchronously closed on the file task runner
52 // before they can be deleted. Pump the RunLoop to avoid leaks.
53 base::RunLoop().RunUntilIdle();
[email protected]21da6eb2008-11-03 17:18:1454 PlatformTest::TearDown();
55 }
[email protected]96d73822011-10-10 02:11:2456
[email protected]6cdfd7f2013-02-08 20:40:1557 const base::FilePath temp_file_path() const { return temp_file_path_; }
[email protected]96d73822011-10-10 02:11:2458
[email protected]21da6eb2008-11-03 17:18:1459 private:
[email protected]6cdfd7f2013-02-08 20:40:1560 base::FilePath temp_file_path_;
[email protected]21da6eb2008-11-03 17:18:1461};
62
[email protected]96d73822011-10-10 02:11:2463namespace {
64
[email protected]21da6eb2008-11-03 17:18:1465TEST_F(FileStreamTest, BasicOpenClose) {
[email protected]96d73822011-10-10 02:11:2466 base::PlatformFile file = base::kInvalidPlatformFileValue;
67 {
[email protected]dd2c4382013-09-07 16:01:4768 FileStream stream(NULL, base::MessageLoopProxy::current());
[email protected]fe57eb22012-02-09 05:59:4069 int rv = stream.OpenSync(temp_file_path(),
[email protected]96d73822011-10-10 02:11:2470 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ);
71 EXPECT_EQ(OK, rv);
72 EXPECT_TRUE(stream.IsOpen());
[email protected]84e0309f2012-02-24 01:56:5973 file = stream.GetPlatformFileForTesting();
[email protected]96d73822011-10-10 02:11:2474 }
75 EXPECT_NE(base::kInvalidPlatformFileValue, file);
76 base::PlatformFileInfo info;
77 // The file should be closed.
78 EXPECT_FALSE(base::GetPlatformFileInfo(file, &info));
79}
80
[email protected]aab1b9e2012-11-06 00:29:5181TEST_F(FileStreamTest, FileHandleNotLeftOpen) {
[email protected]96d73822011-10-10 02:11:2482 bool created = false;
83 ASSERT_EQ(kTestDataSize,
84 file_util::WriteFile(temp_file_path(), kTestData, kTestDataSize));
85 int flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_READ;
86 base::PlatformFile file = base::CreatePlatformFile(
87 temp_file_path(), flags, &created, NULL);
88
89 {
90 // Seek to the beginning of the file and read.
[email protected]dd2c4382013-09-07 16:01:4791 FileStream read_stream(file, flags, NULL,
92 base::MessageLoopProxy::current());
[email protected]96d73822011-10-10 02:11:2493 EXPECT_TRUE(read_stream.IsOpen());
94 }
95
96 EXPECT_NE(base::kInvalidPlatformFileValue, file);
97 base::PlatformFileInfo info;
[email protected]aab1b9e2012-11-06 00:29:5198 // The file should be closed.
99 EXPECT_FALSE(base::GetPlatformFileInfo(file, &info));
[email protected]21da6eb2008-11-03 17:18:14100}
101
[email protected]92aad5222009-02-09 22:26:41102// Test the use of FileStream with a file handle provided at construction.
103TEST_F(FileStreamTest, UseFileHandle) {
104 bool created = false;
105
106 // 1. Test reading with a file handle.
107 ASSERT_EQ(kTestDataSize,
108 file_util::WriteFile(temp_file_path(), kTestData, kTestDataSize));
109 int flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_READ;
110 base::PlatformFile file = base::CreatePlatformFile(
[email protected]ed65fec2010-08-31 19:30:27111 temp_file_path(), flags, &created, NULL);
[email protected]92aad5222009-02-09 22:26:41112
113 // Seek to the beginning of the file and read.
[email protected]dd2c4382013-09-07 16:01:47114 scoped_ptr<FileStream> read_stream(
115 new FileStream(file, flags, NULL, base::MessageLoopProxy::current()));
[email protected]aab1b9e2012-11-06 00:29:51116 ASSERT_EQ(0, read_stream->SeekSync(FROM_BEGIN, 0));
117 ASSERT_EQ(kTestDataSize, read_stream->Available());
[email protected]92aad5222009-02-09 22:26:41118 // Read into buffer and compare.
119 char buffer[kTestDataSize];
[email protected]5eb431e22011-10-12 08:51:38120 ASSERT_EQ(kTestDataSize,
[email protected]aab1b9e2012-11-06 00:29:51121 read_stream->ReadSync(buffer, kTestDataSize));
[email protected]92aad5222009-02-09 22:26:41122 ASSERT_EQ(0, memcmp(kTestData, buffer, kTestDataSize));
[email protected]aab1b9e2012-11-06 00:29:51123 read_stream.reset();
[email protected]92aad5222009-02-09 22:26:41124
125 // 2. Test writing with a file handle.
[email protected]dd3aa792013-07-16 19:10:23126 base::DeleteFile(temp_file_path(), false);
[email protected]92aad5222009-02-09 22:26:41127 flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_WRITE;
[email protected]ed65fec2010-08-31 19:30:27128 file = base::CreatePlatformFile(temp_file_path(), flags, &created, NULL);
[email protected]92aad5222009-02-09 22:26:41129
[email protected]dd2c4382013-09-07 16:01:47130 scoped_ptr<FileStream> write_stream(
131 new FileStream(file, flags, NULL, base::MessageLoopProxy::current()));
[email protected]aab1b9e2012-11-06 00:29:51132 ASSERT_EQ(0, write_stream->SeekSync(FROM_BEGIN, 0));
[email protected]5eb431e22011-10-12 08:51:38133 ASSERT_EQ(kTestDataSize,
[email protected]aab1b9e2012-11-06 00:29:51134 write_stream->WriteSync(kTestData, kTestDataSize));
135 write_stream.reset();
[email protected]92aad5222009-02-09 22:26:41136
137 // Read into buffer and compare to make sure the handle worked fine.
138 ASSERT_EQ(kTestDataSize,
139 file_util::ReadFile(temp_file_path(), buffer, kTestDataSize));
140 ASSERT_EQ(0, memcmp(kTestData, buffer, kTestDataSize));
141}
142
[email protected]21da6eb2008-11-03 17:18:14143TEST_F(FileStreamTest, UseClosedStream) {
[email protected]dd2c4382013-09-07 16:01:47144 FileStream stream(NULL, base::MessageLoopProxy::current());
[email protected]21da6eb2008-11-03 17:18:14145
146 EXPECT_FALSE(stream.IsOpen());
147
148 // Try seeking...
[email protected]cf02541b2012-04-11 08:02:17149 int64 new_offset = stream.SeekSync(FROM_BEGIN, 5);
[email protected]8effd3f62011-03-25 16:29:07150 EXPECT_EQ(ERR_UNEXPECTED, new_offset);
[email protected]21da6eb2008-11-03 17:18:14151
152 // Try available...
153 int64 avail = stream.Available();
[email protected]8effd3f62011-03-25 16:29:07154 EXPECT_EQ(ERR_UNEXPECTED, avail);
[email protected]21da6eb2008-11-03 17:18:14155
156 // Try reading...
157 char buf[10];
[email protected]6b230f42012-02-15 04:08:41158 int rv = stream.ReadSync(buf, arraysize(buf));
[email protected]8effd3f62011-03-25 16:29:07159 EXPECT_EQ(ERR_UNEXPECTED, rv);
[email protected]21da6eb2008-11-03 17:18:14160}
161
162TEST_F(FileStreamTest, BasicRead) {
163 int64 file_size;
164 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
165 EXPECT_TRUE(ok);
166
[email protected]dd2c4382013-09-07 16:01:47167 FileStream stream(NULL, base::MessageLoopProxy::current());
[email protected]f0a51fb52009-03-05 12:46:38168 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14169 base::PLATFORM_FILE_READ;
[email protected]fe57eb22012-02-09 05:59:40170 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07171 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14172
173 int64 total_bytes_avail = stream.Available();
174 EXPECT_EQ(file_size, total_bytes_avail);
175
[email protected]4c2048a2009-03-24 21:02:01176 int total_bytes_read = 0;
[email protected]21da6eb2008-11-03 17:18:14177
178 std::string data_read;
179 for (;;) {
180 char buf[4];
[email protected]6b230f42012-02-15 04:08:41181 rv = stream.ReadSync(buf, arraysize(buf));
[email protected]21da6eb2008-11-03 17:18:14182 EXPECT_LE(0, rv);
183 if (rv <= 0)
184 break;
185 total_bytes_read += rv;
186 data_read.append(buf, rv);
187 }
188 EXPECT_EQ(file_size, total_bytes_read);
[email protected]4c2048a2009-03-24 21:02:01189 EXPECT_EQ(kTestData, data_read);
[email protected]21da6eb2008-11-03 17:18:14190}
191
192TEST_F(FileStreamTest, AsyncRead) {
193 int64 file_size;
194 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
195 EXPECT_TRUE(ok);
196
[email protected]dd2c4382013-09-07 16:01:47197 FileStream stream(NULL, base::MessageLoopProxy::current());
[email protected]f0a51fb52009-03-05 12:46:38198 int flags = base::PLATFORM_FILE_OPEN |
199 base::PLATFORM_FILE_READ |
[email protected]21da6eb2008-11-03 17:18:14200 base::PLATFORM_FILE_ASYNC;
[email protected]66af1d62013-03-06 23:13:20201 TestCompletionCallback callback;
202 int rv = stream.Open(temp_file_path(), flags, callback.callback());
203 EXPECT_EQ(ERR_IO_PENDING, rv);
204 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]21da6eb2008-11-03 17:18:14205
206 int64 total_bytes_avail = stream.Available();
207 EXPECT_EQ(file_size, total_bytes_avail);
208
[email protected]4c2048a2009-03-24 21:02:01209 int total_bytes_read = 0;
[email protected]21da6eb2008-11-03 17:18:14210
211 std::string data_read;
212 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20213 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
[email protected]90499482013-06-01 00:39:50214 rv = stream.Read(buf.get(), buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07215 if (rv == ERR_IO_PENDING)
[email protected]21da6eb2008-11-03 17:18:14216 rv = callback.WaitForResult();
217 EXPECT_LE(0, rv);
218 if (rv <= 0)
219 break;
220 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20221 data_read.append(buf->data(), rv);
[email protected]21da6eb2008-11-03 17:18:14222 }
223 EXPECT_EQ(file_size, total_bytes_read);
[email protected]4c2048a2009-03-24 21:02:01224 EXPECT_EQ(kTestData, data_read);
225}
226
[email protected]06b802b2012-02-22 03:34:54227TEST_F(FileStreamTest, AsyncRead_EarlyDelete) {
228 int64 file_size;
229 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
230 EXPECT_TRUE(ok);
231
[email protected]dd2c4382013-09-07 16:01:47232 scoped_ptr<FileStream> stream(
233 new FileStream(NULL, base::MessageLoopProxy::current()));
[email protected]06b802b2012-02-22 03:34:54234 int flags = base::PLATFORM_FILE_OPEN |
235 base::PLATFORM_FILE_READ |
236 base::PLATFORM_FILE_ASYNC;
237 TestCompletionCallback callback;
238 int rv = stream->Open(temp_file_path(), flags, callback.callback());
239 EXPECT_EQ(ERR_IO_PENDING, rv);
240 EXPECT_EQ(OK, callback.WaitForResult());
241
242 int64 total_bytes_avail = stream->Available();
243 EXPECT_EQ(file_size, total_bytes_avail);
244
245 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
[email protected]90499482013-06-01 00:39:50246 rv = stream->Read(buf.get(), buf->size(), callback.callback());
[email protected]06b802b2012-02-22 03:34:54247 stream.reset(); // Delete instead of closing it.
248 if (rv < 0) {
249 EXPECT_EQ(ERR_IO_PENDING, rv);
250 // The callback should not be called if the request is cancelled.
[email protected]dd2c4382013-09-07 16:01:47251 base::RunLoop().RunUntilIdle();
[email protected]06b802b2012-02-22 03:34:54252 EXPECT_FALSE(callback.have_result());
253 } else {
254 EXPECT_EQ(std::string(kTestData, rv), std::string(buf->data(), rv));
255 }
256}
257
[email protected]21da6eb2008-11-03 17:18:14258TEST_F(FileStreamTest, BasicRead_FromOffset) {
259 int64 file_size;
260 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
261 EXPECT_TRUE(ok);
262
[email protected]dd2c4382013-09-07 16:01:47263 FileStream stream(NULL, base::MessageLoopProxy::current());
[email protected]f0a51fb52009-03-05 12:46:38264 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14265 base::PLATFORM_FILE_READ;
[email protected]fe57eb22012-02-09 05:59:40266 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07267 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14268
269 const int64 kOffset = 3;
[email protected]cf02541b2012-04-11 08:02:17270 int64 new_offset = stream.SeekSync(FROM_BEGIN, kOffset);
[email protected]21da6eb2008-11-03 17:18:14271 EXPECT_EQ(kOffset, new_offset);
272
273 int64 total_bytes_avail = stream.Available();
274 EXPECT_EQ(file_size - kOffset, total_bytes_avail);
275
276 int64 total_bytes_read = 0;
277
278 std::string data_read;
279 for (;;) {
280 char buf[4];
[email protected]6b230f42012-02-15 04:08:41281 rv = stream.ReadSync(buf, arraysize(buf));
[email protected]21da6eb2008-11-03 17:18:14282 EXPECT_LE(0, rv);
283 if (rv <= 0)
284 break;
285 total_bytes_read += rv;
286 data_read.append(buf, rv);
287 }
288 EXPECT_EQ(file_size - kOffset, total_bytes_read);
289 EXPECT_TRUE(data_read == kTestData + kOffset);
[email protected]4c2048a2009-03-24 21:02:01290 EXPECT_EQ(kTestData + kOffset, data_read);
[email protected]21da6eb2008-11-03 17:18:14291}
292
293TEST_F(FileStreamTest, AsyncRead_FromOffset) {
294 int64 file_size;
295 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
296 EXPECT_TRUE(ok);
297
[email protected]dd2c4382013-09-07 16:01:47298 FileStream stream(NULL, base::MessageLoopProxy::current());
[email protected]f0a51fb52009-03-05 12:46:38299 int flags = base::PLATFORM_FILE_OPEN |
300 base::PLATFORM_FILE_READ |
[email protected]21da6eb2008-11-03 17:18:14301 base::PLATFORM_FILE_ASYNC;
[email protected]66af1d62013-03-06 23:13:20302 TestCompletionCallback callback;
303 int rv = stream.Open(temp_file_path(), flags, callback.callback());
304 EXPECT_EQ(ERR_IO_PENDING, rv);
305 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]21da6eb2008-11-03 17:18:14306
[email protected]cf02541b2012-04-11 08:02:17307 TestInt64CompletionCallback callback64;
[email protected]21da6eb2008-11-03 17:18:14308 const int64 kOffset = 3;
[email protected]cf02541b2012-04-11 08:02:17309 rv = stream.Seek(FROM_BEGIN, kOffset, callback64.callback());
310 ASSERT_EQ(ERR_IO_PENDING, rv);
311 int64 new_offset = callback64.WaitForResult();
[email protected]21da6eb2008-11-03 17:18:14312 EXPECT_EQ(kOffset, new_offset);
313
314 int64 total_bytes_avail = stream.Available();
315 EXPECT_EQ(file_size - kOffset, total_bytes_avail);
316
[email protected]4c2048a2009-03-24 21:02:01317 int total_bytes_read = 0;
[email protected]21da6eb2008-11-03 17:18:14318
319 std::string data_read;
320 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20321 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
[email protected]90499482013-06-01 00:39:50322 rv = stream.Read(buf.get(), buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07323 if (rv == ERR_IO_PENDING)
[email protected]21da6eb2008-11-03 17:18:14324 rv = callback.WaitForResult();
325 EXPECT_LE(0, rv);
326 if (rv <= 0)
327 break;
328 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20329 data_read.append(buf->data(), rv);
[email protected]21da6eb2008-11-03 17:18:14330 }
331 EXPECT_EQ(file_size - kOffset, total_bytes_read);
[email protected]4c2048a2009-03-24 21:02:01332 EXPECT_EQ(kTestData + kOffset, data_read);
[email protected]21da6eb2008-11-03 17:18:14333}
334
335TEST_F(FileStreamTest, SeekAround) {
[email protected]dd2c4382013-09-07 16:01:47336 FileStream stream(NULL, base::MessageLoopProxy::current());
[email protected]f0a51fb52009-03-05 12:46:38337 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14338 base::PLATFORM_FILE_READ;
[email protected]fe57eb22012-02-09 05:59:40339 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07340 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14341
342 const int64 kOffset = 3;
[email protected]cf02541b2012-04-11 08:02:17343 int64 new_offset = stream.SeekSync(FROM_BEGIN, kOffset);
[email protected]21da6eb2008-11-03 17:18:14344 EXPECT_EQ(kOffset, new_offset);
345
[email protected]cf02541b2012-04-11 08:02:17346 new_offset = stream.SeekSync(FROM_CURRENT, kOffset);
[email protected]21da6eb2008-11-03 17:18:14347 EXPECT_EQ(2 * kOffset, new_offset);
348
[email protected]cf02541b2012-04-11 08:02:17349 new_offset = stream.SeekSync(FROM_CURRENT, -kOffset);
[email protected]21da6eb2008-11-03 17:18:14350 EXPECT_EQ(kOffset, new_offset);
351
352 const int kTestDataLen = arraysize(kTestData) - 1;
353
[email protected]cf02541b2012-04-11 08:02:17354 new_offset = stream.SeekSync(FROM_END, -kTestDataLen);
355 EXPECT_EQ(0, new_offset);
356}
357
358TEST_F(FileStreamTest, AsyncSeekAround) {
[email protected]dd2c4382013-09-07 16:01:47359 FileStream stream(NULL, base::MessageLoopProxy::current());
[email protected]cf02541b2012-04-11 08:02:17360 int flags = base::PLATFORM_FILE_OPEN |
361 base::PLATFORM_FILE_ASYNC |
362 base::PLATFORM_FILE_READ;
[email protected]66af1d62013-03-06 23:13:20363 TestCompletionCallback callback;
364 int rv = stream.Open(temp_file_path(), flags, callback.callback());
365 EXPECT_EQ(ERR_IO_PENDING, rv);
366 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]cf02541b2012-04-11 08:02:17367
[email protected]66af1d62013-03-06 23:13:20368 TestInt64CompletionCallback callback64;
[email protected]cf02541b2012-04-11 08:02:17369
370 const int64 kOffset = 3;
[email protected]66af1d62013-03-06 23:13:20371 rv = stream.Seek(FROM_BEGIN, kOffset, callback64.callback());
[email protected]cf02541b2012-04-11 08:02:17372 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]66af1d62013-03-06 23:13:20373 int64 new_offset = callback64.WaitForResult();
[email protected]cf02541b2012-04-11 08:02:17374 EXPECT_EQ(kOffset, new_offset);
375
[email protected]66af1d62013-03-06 23:13:20376 rv = stream.Seek(FROM_CURRENT, kOffset, callback64.callback());
[email protected]cf02541b2012-04-11 08:02:17377 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]66af1d62013-03-06 23:13:20378 new_offset = callback64.WaitForResult();
[email protected]cf02541b2012-04-11 08:02:17379 EXPECT_EQ(2 * kOffset, new_offset);
380
[email protected]66af1d62013-03-06 23:13:20381 rv = stream.Seek(FROM_CURRENT, -kOffset, callback64.callback());
[email protected]cf02541b2012-04-11 08:02:17382 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]66af1d62013-03-06 23:13:20383 new_offset = callback64.WaitForResult();
[email protected]cf02541b2012-04-11 08:02:17384 EXPECT_EQ(kOffset, new_offset);
385
386 const int kTestDataLen = arraysize(kTestData) - 1;
387
[email protected]66af1d62013-03-06 23:13:20388 rv = stream.Seek(FROM_END, -kTestDataLen, callback64.callback());
[email protected]cf02541b2012-04-11 08:02:17389 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]66af1d62013-03-06 23:13:20390 new_offset = callback64.WaitForResult();
[email protected]21da6eb2008-11-03 17:18:14391 EXPECT_EQ(0, new_offset);
392}
393
394TEST_F(FileStreamTest, BasicWrite) {
[email protected]dd2c4382013-09-07 16:01:47395 scoped_ptr<FileStream> stream(
396 new FileStream(NULL, base::MessageLoopProxy::current()));
[email protected]f0a51fb52009-03-05 12:46:38397 int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
[email protected]21da6eb2008-11-03 17:18:14398 base::PLATFORM_FILE_WRITE;
[email protected]aab1b9e2012-11-06 00:29:51399 int rv = stream->OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07400 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14401
402 int64 file_size;
403 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
404 EXPECT_TRUE(ok);
405 EXPECT_EQ(0, file_size);
406
[email protected]aab1b9e2012-11-06 00:29:51407 rv = stream->WriteSync(kTestData, kTestDataSize);
[email protected]21da6eb2008-11-03 17:18:14408 EXPECT_EQ(kTestDataSize, rv);
[email protected]aab1b9e2012-11-06 00:29:51409 stream.reset();
[email protected]21da6eb2008-11-03 17:18:14410
411 ok = file_util::GetFileSize(temp_file_path(), &file_size);
412 EXPECT_TRUE(ok);
413 EXPECT_EQ(kTestDataSize, file_size);
414}
415
416TEST_F(FileStreamTest, AsyncWrite) {
[email protected]dd2c4382013-09-07 16:01:47417 FileStream stream(NULL, base::MessageLoopProxy::current());
[email protected]f0a51fb52009-03-05 12:46:38418 int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
419 base::PLATFORM_FILE_WRITE |
[email protected]21da6eb2008-11-03 17:18:14420 base::PLATFORM_FILE_ASYNC;
[email protected]66af1d62013-03-06 23:13:20421 TestCompletionCallback callback;
422 int rv = stream.Open(temp_file_path(), flags, callback.callback());
423 EXPECT_EQ(ERR_IO_PENDING, rv);
424 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]21da6eb2008-11-03 17:18:14425
426 int64 file_size;
427 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
428 EXPECT_TRUE(ok);
429 EXPECT_EQ(0, file_size);
430
[email protected]4c2048a2009-03-24 21:02:01431 int total_bytes_written = 0;
[email protected]21da6eb2008-11-03 17:18:14432
[email protected]9f49afb2012-02-16 09:59:20433 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
434 scoped_refptr<DrainableIOBuffer> drainable =
[email protected]90499482013-06-01 00:39:50435 new DrainableIOBuffer(buf.get(), buf->size());
[email protected]21da6eb2008-11-03 17:18:14436 while (total_bytes_written != kTestDataSize) {
[email protected]90499482013-06-01 00:39:50437 rv = stream.Write(
438 drainable.get(), drainable->BytesRemaining(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07439 if (rv == ERR_IO_PENDING)
[email protected]21da6eb2008-11-03 17:18:14440 rv = callback.WaitForResult();
441 EXPECT_LT(0, rv);
442 if (rv <= 0)
443 break;
[email protected]9f49afb2012-02-16 09:59:20444 drainable->DidConsume(rv);
[email protected]21da6eb2008-11-03 17:18:14445 total_bytes_written += rv;
446 }
447 ok = file_util::GetFileSize(temp_file_path(), &file_size);
448 EXPECT_TRUE(ok);
449 EXPECT_EQ(file_size, total_bytes_written);
450}
451
[email protected]aab1b9e2012-11-06 00:29:51452TEST_F(FileStreamTest, AsyncWrite_EarlyDelete) {
[email protected]dd2c4382013-09-07 16:01:47453 scoped_ptr<FileStream> stream(
454 new FileStream(NULL, base::MessageLoopProxy::current()));
[email protected]4c2048a2009-03-24 21:02:01455 int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
456 base::PLATFORM_FILE_WRITE |
457 base::PLATFORM_FILE_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
463 int64 file_size;
464 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
465 EXPECT_TRUE(ok);
466 EXPECT_EQ(0, file_size);
467
[email protected]9f49afb2012-02-16 09:59:20468 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
[email protected]90499482013-06-01 00:39:50469 rv = stream->Write(buf.get(), buf->size(), callback.callback());
[email protected]aab1b9e2012-11-06 00:29:51470 stream.reset();
[email protected]3828a752009-06-03 23:05:59471 if (rv < 0) {
[email protected]8effd3f62011-03-25 16:29:07472 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3828a752009-06-03 23:05:59473 // The callback should not be called if the request is cancelled.
[email protected]dd2c4382013-09-07 16:01:47474 base::RunLoop().RunUntilIdle();
[email protected]3828a752009-06-03 23:05:59475 EXPECT_FALSE(callback.have_result());
476 } else {
477 ok = file_util::GetFileSize(temp_file_path(), &file_size);
478 EXPECT_TRUE(ok);
479 EXPECT_EQ(file_size, rv);
480 }
[email protected]4c2048a2009-03-24 21:02:01481}
482
[email protected]21da6eb2008-11-03 17:18:14483TEST_F(FileStreamTest, BasicWrite_FromOffset) {
[email protected]dd2c4382013-09-07 16:01:47484 scoped_ptr<FileStream> stream(
485 new FileStream(NULL, base::MessageLoopProxy::current()));
[email protected]f0a51fb52009-03-05 12:46:38486 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14487 base::PLATFORM_FILE_WRITE;
[email protected]aab1b9e2012-11-06 00:29:51488 int rv = stream->OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07489 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14490
491 int64 file_size;
492 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
493 EXPECT_TRUE(ok);
494 EXPECT_EQ(kTestDataSize, file_size);
495
496 const int64 kOffset = 0;
[email protected]aab1b9e2012-11-06 00:29:51497 int64 new_offset = stream->SeekSync(FROM_END, kOffset);
[email protected]21da6eb2008-11-03 17:18:14498 EXPECT_EQ(kTestDataSize, new_offset);
499
[email protected]aab1b9e2012-11-06 00:29:51500 rv = stream->WriteSync(kTestData, kTestDataSize);
[email protected]21da6eb2008-11-03 17:18:14501 EXPECT_EQ(kTestDataSize, rv);
[email protected]aab1b9e2012-11-06 00:29:51502 stream.reset();
[email protected]21da6eb2008-11-03 17:18:14503
504 ok = file_util::GetFileSize(temp_file_path(), &file_size);
505 EXPECT_TRUE(ok);
506 EXPECT_EQ(kTestDataSize * 2, file_size);
507}
508
509TEST_F(FileStreamTest, AsyncWrite_FromOffset) {
510 int64 file_size;
511 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
512 EXPECT_TRUE(ok);
513
[email protected]dd2c4382013-09-07 16:01:47514 FileStream stream(NULL, base::MessageLoopProxy::current());
[email protected]f0a51fb52009-03-05 12:46:38515 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14516 base::PLATFORM_FILE_WRITE |
517 base::PLATFORM_FILE_ASYNC;
[email protected]66af1d62013-03-06 23:13:20518 TestCompletionCallback callback;
519 int rv = stream.Open(temp_file_path(), flags, callback.callback());
520 EXPECT_EQ(ERR_IO_PENDING, rv);
521 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]21da6eb2008-11-03 17:18:14522
[email protected]cf02541b2012-04-11 08:02:17523 TestInt64CompletionCallback callback64;
[email protected]21da6eb2008-11-03 17:18:14524 const int64 kOffset = 0;
[email protected]cf02541b2012-04-11 08:02:17525 rv = stream.Seek(FROM_END, kOffset, callback64.callback());
526 ASSERT_EQ(ERR_IO_PENDING, rv);
527 int64 new_offset = callback64.WaitForResult();
[email protected]21da6eb2008-11-03 17:18:14528 EXPECT_EQ(kTestDataSize, new_offset);
529
[email protected]4c2048a2009-03-24 21:02:01530 int total_bytes_written = 0;
[email protected]21da6eb2008-11-03 17:18:14531
[email protected]9f49afb2012-02-16 09:59:20532 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
533 scoped_refptr<DrainableIOBuffer> drainable =
[email protected]90499482013-06-01 00:39:50534 new DrainableIOBuffer(buf.get(), buf->size());
[email protected]21da6eb2008-11-03 17:18:14535 while (total_bytes_written != kTestDataSize) {
[email protected]90499482013-06-01 00:39:50536 rv = stream.Write(
537 drainable.get(), drainable->BytesRemaining(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07538 if (rv == ERR_IO_PENDING)
[email protected]21da6eb2008-11-03 17:18:14539 rv = callback.WaitForResult();
540 EXPECT_LT(0, rv);
541 if (rv <= 0)
542 break;
[email protected]9f49afb2012-02-16 09:59:20543 drainable->DidConsume(rv);
[email protected]21da6eb2008-11-03 17:18:14544 total_bytes_written += rv;
545 }
546 ok = file_util::GetFileSize(temp_file_path(), &file_size);
547 EXPECT_TRUE(ok);
548 EXPECT_EQ(file_size, kTestDataSize * 2);
549}
550
551TEST_F(FileStreamTest, BasicReadWrite) {
552 int64 file_size;
553 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
554 EXPECT_TRUE(ok);
555
[email protected]dd2c4382013-09-07 16:01:47556 scoped_ptr<FileStream> stream(
557 new FileStream(NULL, base::MessageLoopProxy::current()));
[email protected]f0a51fb52009-03-05 12:46:38558 int flags = base::PLATFORM_FILE_OPEN |
559 base::PLATFORM_FILE_READ |
[email protected]21da6eb2008-11-03 17:18:14560 base::PLATFORM_FILE_WRITE;
[email protected]aab1b9e2012-11-06 00:29:51561 int rv = stream->OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07562 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14563
[email protected]aab1b9e2012-11-06 00:29:51564 int64 total_bytes_avail = stream->Available();
[email protected]21da6eb2008-11-03 17:18:14565 EXPECT_EQ(file_size, total_bytes_avail);
566
[email protected]4c2048a2009-03-24 21:02:01567 int total_bytes_read = 0;
[email protected]21da6eb2008-11-03 17:18:14568
569 std::string data_read;
570 for (;;) {
571 char buf[4];
[email protected]aab1b9e2012-11-06 00:29:51572 rv = stream->ReadSync(buf, arraysize(buf));
[email protected]21da6eb2008-11-03 17:18:14573 EXPECT_LE(0, rv);
574 if (rv <= 0)
575 break;
576 total_bytes_read += rv;
577 data_read.append(buf, rv);
578 }
579 EXPECT_EQ(file_size, total_bytes_read);
580 EXPECT_TRUE(data_read == kTestData);
581
[email protected]aab1b9e2012-11-06 00:29:51582 rv = stream->WriteSync(kTestData, kTestDataSize);
[email protected]21da6eb2008-11-03 17:18:14583 EXPECT_EQ(kTestDataSize, rv);
[email protected]aab1b9e2012-11-06 00:29:51584 stream.reset();
[email protected]21da6eb2008-11-03 17:18:14585
586 ok = file_util::GetFileSize(temp_file_path(), &file_size);
587 EXPECT_TRUE(ok);
588 EXPECT_EQ(kTestDataSize * 2, file_size);
589}
590
[email protected]4c2048a2009-03-24 21:02:01591TEST_F(FileStreamTest, BasicWriteRead) {
592 int64 file_size;
593 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
594 EXPECT_TRUE(ok);
595
[email protected]dd2c4382013-09-07 16:01:47596 scoped_ptr<FileStream> stream(
597 new FileStream(NULL, base::MessageLoopProxy::current()));
[email protected]4c2048a2009-03-24 21:02:01598 int flags = base::PLATFORM_FILE_OPEN |
599 base::PLATFORM_FILE_READ |
600 base::PLATFORM_FILE_WRITE;
[email protected]aab1b9e2012-11-06 00:29:51601 int rv = stream->OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07602 EXPECT_EQ(OK, rv);
[email protected]4c2048a2009-03-24 21:02:01603
[email protected]aab1b9e2012-11-06 00:29:51604 int64 total_bytes_avail = stream->Available();
[email protected]4c2048a2009-03-24 21:02:01605 EXPECT_EQ(file_size, total_bytes_avail);
606
[email protected]aab1b9e2012-11-06 00:29:51607 int64 offset = stream->SeekSync(FROM_END, 0);
[email protected]4c2048a2009-03-24 21:02:01608 EXPECT_EQ(offset, file_size);
609
[email protected]aab1b9e2012-11-06 00:29:51610 rv = stream->WriteSync(kTestData, kTestDataSize);
[email protected]4c2048a2009-03-24 21:02:01611 EXPECT_EQ(kTestDataSize, rv);
612
[email protected]aab1b9e2012-11-06 00:29:51613 offset = stream->SeekSync(FROM_BEGIN, 0);
[email protected]4c2048a2009-03-24 21:02:01614 EXPECT_EQ(0, offset);
615
616 int64 total_bytes_read = 0;
617
618 std::string data_read;
619 for (;;) {
620 char buf[4];
[email protected]aab1b9e2012-11-06 00:29:51621 rv = stream->ReadSync(buf, arraysize(buf));
[email protected]4c2048a2009-03-24 21:02:01622 EXPECT_LE(0, rv);
623 if (rv <= 0)
624 break;
625 total_bytes_read += rv;
626 data_read.append(buf, rv);
627 }
[email protected]aab1b9e2012-11-06 00:29:51628 stream.reset();
[email protected]4c2048a2009-03-24 21:02:01629
630 ok = file_util::GetFileSize(temp_file_path(), &file_size);
631 EXPECT_TRUE(ok);
632 EXPECT_EQ(kTestDataSize * 2, file_size);
633 EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
634
635 const std::string kExpectedFileData =
636 std::string(kTestData) + std::string(kTestData);
637 EXPECT_EQ(kExpectedFileData, data_read);
638}
639
640TEST_F(FileStreamTest, BasicAsyncReadWrite) {
641 int64 file_size;
642 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
643 EXPECT_TRUE(ok);
644
[email protected]dd2c4382013-09-07 16:01:47645 scoped_ptr<FileStream> stream(
646 new FileStream(NULL, base::MessageLoopProxy::current()));
[email protected]4c2048a2009-03-24 21:02:01647 int flags = base::PLATFORM_FILE_OPEN |
648 base::PLATFORM_FILE_READ |
649 base::PLATFORM_FILE_WRITE |
650 base::PLATFORM_FILE_ASYNC;
[email protected]66af1d62013-03-06 23:13:20651 TestCompletionCallback callback;
652 int rv = stream->Open(temp_file_path(), flags, callback.callback());
653 EXPECT_EQ(ERR_IO_PENDING, rv);
654 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]4c2048a2009-03-24 21:02:01655
[email protected]aab1b9e2012-11-06 00:29:51656 int64 total_bytes_avail = stream->Available();
[email protected]4c2048a2009-03-24 21:02:01657 EXPECT_EQ(file_size, total_bytes_avail);
658
[email protected]4c2048a2009-03-24 21:02:01659 int64 total_bytes_read = 0;
660
661 std::string data_read;
662 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20663 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
[email protected]90499482013-06-01 00:39:50664 rv = stream->Read(buf.get(), buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07665 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01666 rv = callback.WaitForResult();
667 EXPECT_LE(0, rv);
668 if (rv <= 0)
669 break;
670 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20671 data_read.append(buf->data(), rv);
[email protected]4c2048a2009-03-24 21:02:01672 }
673 EXPECT_EQ(file_size, total_bytes_read);
674 EXPECT_TRUE(data_read == kTestData);
675
676 int total_bytes_written = 0;
677
[email protected]9f49afb2012-02-16 09:59:20678 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
679 scoped_refptr<DrainableIOBuffer> drainable =
[email protected]90499482013-06-01 00:39:50680 new DrainableIOBuffer(buf.get(), buf->size());
[email protected]4c2048a2009-03-24 21:02:01681 while (total_bytes_written != kTestDataSize) {
[email protected]90499482013-06-01 00:39:50682 rv = stream->Write(
683 drainable.get(), drainable->BytesRemaining(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07684 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01685 rv = callback.WaitForResult();
686 EXPECT_LT(0, rv);
687 if (rv <= 0)
688 break;
[email protected]9f49afb2012-02-16 09:59:20689 drainable->DidConsume(rv);
[email protected]4c2048a2009-03-24 21:02:01690 total_bytes_written += rv;
691 }
692
[email protected]aab1b9e2012-11-06 00:29:51693 stream.reset();
[email protected]4c2048a2009-03-24 21:02:01694
695 ok = file_util::GetFileSize(temp_file_path(), &file_size);
696 EXPECT_TRUE(ok);
697 EXPECT_EQ(kTestDataSize * 2, file_size);
698}
699
700TEST_F(FileStreamTest, BasicAsyncWriteRead) {
701 int64 file_size;
702 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
703 EXPECT_TRUE(ok);
704
[email protected]dd2c4382013-09-07 16:01:47705 scoped_ptr<FileStream> stream(
706 new FileStream(NULL, base::MessageLoopProxy::current()));
[email protected]4c2048a2009-03-24 21:02:01707 int flags = base::PLATFORM_FILE_OPEN |
708 base::PLATFORM_FILE_READ |
709 base::PLATFORM_FILE_WRITE |
710 base::PLATFORM_FILE_ASYNC;
[email protected]66af1d62013-03-06 23:13:20711 TestCompletionCallback callback;
712 int rv = stream->Open(temp_file_path(), flags, callback.callback());
713 EXPECT_EQ(ERR_IO_PENDING, rv);
714 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]4c2048a2009-03-24 21:02:01715
[email protected]aab1b9e2012-11-06 00:29:51716 int64 total_bytes_avail = stream->Available();
[email protected]4c2048a2009-03-24 21:02:01717 EXPECT_EQ(file_size, total_bytes_avail);
718
[email protected]cf02541b2012-04-11 08:02:17719 TestInt64CompletionCallback callback64;
[email protected]aab1b9e2012-11-06 00:29:51720 rv = stream->Seek(FROM_END, 0, callback64.callback());
[email protected]cf02541b2012-04-11 08:02:17721 ASSERT_EQ(ERR_IO_PENDING, rv);
722 int64 offset = callback64.WaitForResult();
[email protected]4c2048a2009-03-24 21:02:01723 EXPECT_EQ(offset, file_size);
724
[email protected]4c2048a2009-03-24 21:02:01725 int total_bytes_written = 0;
726
[email protected]9f49afb2012-02-16 09:59:20727 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
728 scoped_refptr<DrainableIOBuffer> drainable =
[email protected]90499482013-06-01 00:39:50729 new DrainableIOBuffer(buf.get(), buf->size());
[email protected]4c2048a2009-03-24 21:02:01730 while (total_bytes_written != kTestDataSize) {
[email protected]90499482013-06-01 00:39:50731 rv = stream->Write(
732 drainable.get(), drainable->BytesRemaining(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07733 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01734 rv = callback.WaitForResult();
735 EXPECT_LT(0, rv);
736 if (rv <= 0)
737 break;
[email protected]9f49afb2012-02-16 09:59:20738 drainable->DidConsume(rv);
[email protected]4c2048a2009-03-24 21:02:01739 total_bytes_written += rv;
740 }
741
742 EXPECT_EQ(kTestDataSize, total_bytes_written);
743
[email protected]aab1b9e2012-11-06 00:29:51744 rv = stream->Seek(FROM_BEGIN, 0, callback64.callback());
[email protected]cf02541b2012-04-11 08:02:17745 ASSERT_EQ(ERR_IO_PENDING, rv);
746 offset = callback64.WaitForResult();
[email protected]4c2048a2009-03-24 21:02:01747 EXPECT_EQ(0, offset);
748
749 int total_bytes_read = 0;
750
751 std::string data_read;
752 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20753 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
[email protected]90499482013-06-01 00:39:50754 rv = stream->Read(buf.get(), buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07755 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01756 rv = callback.WaitForResult();
757 EXPECT_LE(0, rv);
758 if (rv <= 0)
759 break;
760 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20761 data_read.append(buf->data(), rv);
[email protected]4c2048a2009-03-24 21:02:01762 }
[email protected]aab1b9e2012-11-06 00:29:51763 stream.reset();
[email protected]4c2048a2009-03-24 21:02:01764
765 ok = file_util::GetFileSize(temp_file_path(), &file_size);
766 EXPECT_TRUE(ok);
767 EXPECT_EQ(kTestDataSize * 2, file_size);
768
769 EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
770 const std::string kExpectedFileData =
771 std::string(kTestData) + std::string(kTestData);
772 EXPECT_EQ(kExpectedFileData, data_read);
773}
774
[email protected]5eb431e22011-10-12 08:51:38775class TestWriteReadCompletionCallback {
[email protected]4c2048a2009-03-24 21:02:01776 public:
[email protected]90499482013-06-01 00:39:50777 TestWriteReadCompletionCallback(FileStream* stream,
778 int* total_bytes_written,
779 int* total_bytes_read,
780 std::string* data_read)
[email protected]4c2048a2009-03-24 21:02:01781 : result_(0),
782 have_result_(false),
783 waiting_for_result_(false),
784 stream_(stream),
785 total_bytes_written_(total_bytes_written),
786 total_bytes_read_(total_bytes_read),
[email protected]5eb431e22011-10-12 08:51:38787 data_read_(data_read),
788 callback_(base::Bind(&TestWriteReadCompletionCallback::OnComplete,
[email protected]9f49afb2012-02-16 09:59:20789 base::Unretained(this))),
790 test_data_(CreateTestDataBuffer()),
[email protected]90499482013-06-01 00:39:50791 drainable_(new DrainableIOBuffer(test_data_.get(), kTestDataSize)) {}
[email protected]4c2048a2009-03-24 21:02:01792
793 int WaitForResult() {
794 DCHECK(!waiting_for_result_);
795 while (!have_result_) {
796 waiting_for_result_ = true;
[email protected]dd2c4382013-09-07 16:01:47797 base::RunLoop().Run();
[email protected]4c2048a2009-03-24 21:02:01798 waiting_for_result_ = false;
799 }
800 have_result_ = false; // auto-reset for next callback
801 return result_;
802 }
803
[email protected]5eb431e22011-10-12 08:51:38804 const CompletionCallback& callback() const { return callback_; }
805
[email protected]4c2048a2009-03-24 21:02:01806 private:
[email protected]5eb431e22011-10-12 08:51:38807 void OnComplete(int result) {
808 DCHECK_LT(0, result);
809 *total_bytes_written_ += result;
[email protected]4c2048a2009-03-24 21:02:01810
811 int rv;
812
813 if (*total_bytes_written_ != kTestDataSize) {
814 // Recurse to finish writing all data.
815 int total_bytes_written = 0, total_bytes_read = 0;
816 std::string data_read;
[email protected]5eb431e22011-10-12 08:51:38817 TestWriteReadCompletionCallback callback(
[email protected]4c2048a2009-03-24 21:02:01818 stream_, &total_bytes_written, &total_bytes_read, &data_read);
[email protected]90499482013-06-01 00:39:50819 rv = stream_->Write(
820 drainable_.get(), drainable_->BytesRemaining(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07821 DCHECK_EQ(ERR_IO_PENDING, rv);
[email protected]4c2048a2009-03-24 21:02:01822 rv = callback.WaitForResult();
[email protected]9f49afb2012-02-16 09:59:20823 drainable_->DidConsume(total_bytes_written);
[email protected]4c2048a2009-03-24 21:02:01824 *total_bytes_written_ += total_bytes_written;
825 *total_bytes_read_ += total_bytes_read;
826 *data_read_ += data_read;
827 } else { // We're done writing all data. Start reading the data.
[email protected]cf02541b2012-04-11 08:02:17828 stream_->SeekSync(FROM_BEGIN, 0);
[email protected]4c2048a2009-03-24 21:02:01829
[email protected]5eb431e22011-10-12 08:51:38830 TestCompletionCallback callback;
[email protected]4c2048a2009-03-24 21:02:01831 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20832 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
[email protected]90499482013-06-01 00:39:50833 rv = stream_->Read(buf.get(), buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07834 if (rv == ERR_IO_PENDING) {
[email protected]2da659e2013-05-23 20:51:34835 base::MessageLoop::ScopedNestableTaskAllower allow(
836 base::MessageLoop::current());
[email protected]4c2048a2009-03-24 21:02:01837 rv = callback.WaitForResult();
[email protected]4c2048a2009-03-24 21:02:01838 }
839 EXPECT_LE(0, rv);
840 if (rv <= 0)
841 break;
842 *total_bytes_read_ += rv;
[email protected]9f49afb2012-02-16 09:59:20843 data_read_->append(buf->data(), rv);
[email protected]4c2048a2009-03-24 21:02:01844 }
845 }
846
847 result_ = *total_bytes_written_;
848 have_result_ = true;
849 if (waiting_for_result_)
[email protected]2da659e2013-05-23 20:51:34850 base::MessageLoop::current()->Quit();
[email protected]4c2048a2009-03-24 21:02:01851 }
852
853 int result_;
854 bool have_result_;
855 bool waiting_for_result_;
[email protected]8effd3f62011-03-25 16:29:07856 FileStream* stream_;
[email protected]4c2048a2009-03-24 21:02:01857 int* total_bytes_written_;
858 int* total_bytes_read_;
859 std::string* data_read_;
[email protected]5eb431e22011-10-12 08:51:38860 const CompletionCallback callback_;
[email protected]9f49afb2012-02-16 09:59:20861 scoped_refptr<IOBufferWithSize> test_data_;
862 scoped_refptr<DrainableIOBuffer> drainable_;
[email protected]4c2048a2009-03-24 21:02:01863
[email protected]5eb431e22011-10-12 08:51:38864 DISALLOW_COPY_AND_ASSIGN(TestWriteReadCompletionCallback);
[email protected]4c2048a2009-03-24 21:02:01865};
866
867TEST_F(FileStreamTest, AsyncWriteRead) {
868 int64 file_size;
869 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
870 EXPECT_TRUE(ok);
871
[email protected]dd2c4382013-09-07 16:01:47872 scoped_ptr<FileStream> stream(
873 new FileStream(NULL, base::MessageLoopProxy::current()));
[email protected]4c2048a2009-03-24 21:02:01874 int flags = base::PLATFORM_FILE_OPEN |
875 base::PLATFORM_FILE_READ |
876 base::PLATFORM_FILE_WRITE |
877 base::PLATFORM_FILE_ASYNC;
[email protected]66af1d62013-03-06 23:13:20878 TestCompletionCallback open_callback;
879 int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
880 EXPECT_EQ(ERR_IO_PENDING, rv);
881 EXPECT_EQ(OK, open_callback.WaitForResult());
[email protected]4c2048a2009-03-24 21:02:01882
[email protected]aab1b9e2012-11-06 00:29:51883 int64 total_bytes_avail = stream->Available();
[email protected]4c2048a2009-03-24 21:02:01884 EXPECT_EQ(file_size, total_bytes_avail);
885
[email protected]aab1b9e2012-11-06 00:29:51886 int64 offset = stream->SeekSync(FROM_END, 0);
[email protected]4c2048a2009-03-24 21:02:01887 EXPECT_EQ(offset, file_size);
888
889 int total_bytes_written = 0;
890 int total_bytes_read = 0;
891 std::string data_read;
[email protected]aab1b9e2012-11-06 00:29:51892 TestWriteReadCompletionCallback callback(stream.get(), &total_bytes_written,
[email protected]4c2048a2009-03-24 21:02:01893 &total_bytes_read, &data_read);
894
[email protected]9f49afb2012-02-16 09:59:20895 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
[email protected]90499482013-06-01 00:39:50896 rv = stream->Write(buf.get(), buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07897 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01898 rv = callback.WaitForResult();
899 EXPECT_LT(0, rv);
900 EXPECT_EQ(kTestDataSize, total_bytes_written);
901
[email protected]aab1b9e2012-11-06 00:29:51902 stream.reset();
[email protected]4c2048a2009-03-24 21:02:01903
904 ok = file_util::GetFileSize(temp_file_path(), &file_size);
905 EXPECT_TRUE(ok);
906 EXPECT_EQ(kTestDataSize * 2, file_size);
907
908 EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
909 const std::string kExpectedFileData =
910 std::string(kTestData) + std::string(kTestData);
911 EXPECT_EQ(kExpectedFileData, data_read);
912}
913
[email protected]5eb431e22011-10-12 08:51:38914class TestWriteCloseCompletionCallback {
[email protected]4c2048a2009-03-24 21:02:01915 public:
[email protected]5eb431e22011-10-12 08:51:38916 TestWriteCloseCompletionCallback(FileStream* stream, int* total_bytes_written)
[email protected]4c2048a2009-03-24 21:02:01917 : result_(0),
918 have_result_(false),
919 waiting_for_result_(false),
920 stream_(stream),
[email protected]5eb431e22011-10-12 08:51:38921 total_bytes_written_(total_bytes_written),
922 callback_(base::Bind(&TestWriteCloseCompletionCallback::OnComplete,
[email protected]9f49afb2012-02-16 09:59:20923 base::Unretained(this))),
924 test_data_(CreateTestDataBuffer()),
[email protected]90499482013-06-01 00:39:50925 drainable_(new DrainableIOBuffer(test_data_.get(), kTestDataSize)) {}
[email protected]4c2048a2009-03-24 21:02:01926
927 int WaitForResult() {
928 DCHECK(!waiting_for_result_);
929 while (!have_result_) {
930 waiting_for_result_ = true;
[email protected]dd2c4382013-09-07 16:01:47931 base::RunLoop().Run();
[email protected]4c2048a2009-03-24 21:02:01932 waiting_for_result_ = false;
933 }
934 have_result_ = false; // auto-reset for next callback
935 return result_;
936 }
937
[email protected]5eb431e22011-10-12 08:51:38938 const CompletionCallback& callback() const { return callback_; }
939
[email protected]4c2048a2009-03-24 21:02:01940 private:
[email protected]5eb431e22011-10-12 08:51:38941 void OnComplete(int result) {
942 DCHECK_LT(0, result);
943 *total_bytes_written_ += result;
[email protected]4c2048a2009-03-24 21:02:01944
945 int rv;
946
947 if (*total_bytes_written_ != kTestDataSize) {
948 // Recurse to finish writing all data.
949 int total_bytes_written = 0;
[email protected]5eb431e22011-10-12 08:51:38950 TestWriteCloseCompletionCallback callback(stream_, &total_bytes_written);
[email protected]90499482013-06-01 00:39:50951 rv = stream_->Write(
952 drainable_.get(), drainable_->BytesRemaining(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07953 DCHECK_EQ(ERR_IO_PENDING, rv);
[email protected]4c2048a2009-03-24 21:02:01954 rv = callback.WaitForResult();
[email protected]9f49afb2012-02-16 09:59:20955 drainable_->DidConsume(total_bytes_written);
[email protected]4c2048a2009-03-24 21:02:01956 *total_bytes_written_ += total_bytes_written;
[email protected]4c2048a2009-03-24 21:02:01957 }
958
959 result_ = *total_bytes_written_;
960 have_result_ = true;
961 if (waiting_for_result_)
[email protected]2da659e2013-05-23 20:51:34962 base::MessageLoop::current()->Quit();
[email protected]4c2048a2009-03-24 21:02:01963 }
964
965 int result_;
966 bool have_result_;
967 bool waiting_for_result_;
[email protected]8effd3f62011-03-25 16:29:07968 FileStream* stream_;
[email protected]4c2048a2009-03-24 21:02:01969 int* total_bytes_written_;
[email protected]5eb431e22011-10-12 08:51:38970 const CompletionCallback callback_;
[email protected]9f49afb2012-02-16 09:59:20971 scoped_refptr<IOBufferWithSize> test_data_;
972 scoped_refptr<DrainableIOBuffer> drainable_;
[email protected]4c2048a2009-03-24 21:02:01973
[email protected]5eb431e22011-10-12 08:51:38974 DISALLOW_COPY_AND_ASSIGN(TestWriteCloseCompletionCallback);
[email protected]4c2048a2009-03-24 21:02:01975};
976
977TEST_F(FileStreamTest, AsyncWriteClose) {
978 int64 file_size;
979 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
980 EXPECT_TRUE(ok);
981
[email protected]dd2c4382013-09-07 16:01:47982 scoped_ptr<FileStream> stream(
983 new FileStream(NULL, base::MessageLoopProxy::current()));
[email protected]4c2048a2009-03-24 21:02:01984 int flags = base::PLATFORM_FILE_OPEN |
985 base::PLATFORM_FILE_READ |
986 base::PLATFORM_FILE_WRITE |
987 base::PLATFORM_FILE_ASYNC;
[email protected]66af1d62013-03-06 23:13:20988 TestCompletionCallback open_callback;
989 int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
990 EXPECT_EQ(ERR_IO_PENDING, rv);
991 EXPECT_EQ(OK, open_callback.WaitForResult());
[email protected]4c2048a2009-03-24 21:02:01992
[email protected]aab1b9e2012-11-06 00:29:51993 int64 total_bytes_avail = stream->Available();
[email protected]4c2048a2009-03-24 21:02:01994 EXPECT_EQ(file_size, total_bytes_avail);
995
[email protected]aab1b9e2012-11-06 00:29:51996 int64 offset = stream->SeekSync(FROM_END, 0);
[email protected]4c2048a2009-03-24 21:02:01997 EXPECT_EQ(offset, file_size);
998
999 int total_bytes_written = 0;
[email protected]aab1b9e2012-11-06 00:29:511000 TestWriteCloseCompletionCallback callback(stream.get(), &total_bytes_written);
[email protected]4c2048a2009-03-24 21:02:011001
[email protected]9f49afb2012-02-16 09:59:201002 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
[email protected]90499482013-06-01 00:39:501003 rv = stream->Write(buf.get(), buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:071004 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:011005 total_bytes_written = callback.WaitForResult();
1006 EXPECT_LT(0, total_bytes_written);
1007 EXPECT_EQ(kTestDataSize, total_bytes_written);
1008
[email protected]aab1b9e2012-11-06 00:29:511009 stream.reset();
1010
[email protected]4c2048a2009-03-24 21:02:011011 ok = file_util::GetFileSize(temp_file_path(), &file_size);
1012 EXPECT_TRUE(ok);
1013 EXPECT_EQ(kTestDataSize * 2, file_size);
1014}
1015
[email protected]0643a492009-03-09 15:49:201016// Tests truncating a file.
1017TEST_F(FileStreamTest, Truncate) {
1018 int flags = base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE;
1019
[email protected]dd2c4382013-09-07 16:01:471020 scoped_ptr<FileStream> write_stream(
1021 new FileStream(NULL, base::MessageLoopProxy::current()));
[email protected]aab1b9e2012-11-06 00:29:511022 ASSERT_EQ(OK, write_stream->OpenSync(temp_file_path(), flags));
[email protected]0643a492009-03-09 15:49:201023
1024 // Write some data to the file.
1025 const char test_data[] = "0123456789";
[email protected]aab1b9e2012-11-06 00:29:511026 write_stream->WriteSync(test_data, arraysize(test_data));
[email protected]0643a492009-03-09 15:49:201027
1028 // Truncate the file.
[email protected]aab1b9e2012-11-06 00:29:511029 ASSERT_EQ(4, write_stream->Truncate(4));
[email protected]0643a492009-03-09 15:49:201030
1031 // Write again.
[email protected]aab1b9e2012-11-06 00:29:511032 write_stream->WriteSync(test_data, 4);
[email protected]0643a492009-03-09 15:49:201033
1034 // Close the stream.
[email protected]aab1b9e2012-11-06 00:29:511035 write_stream.reset();
[email protected]0643a492009-03-09 15:49:201036
1037 // Read in the contents and make sure we get back what we expected.
1038 std::string read_contents;
[email protected]82f84b92013-08-30 18:23:501039 EXPECT_TRUE(base::ReadFileToString(temp_file_path(), &read_contents));
[email protected]0643a492009-03-09 15:49:201040
[email protected]4c2048a2009-03-24 21:02:011041 EXPECT_EQ("01230123", read_contents);
[email protected]0643a492009-03-09 15:49:201042}
1043
[email protected]dbb747c2012-02-29 19:29:471044TEST_F(FileStreamTest, AsyncOpenAndDelete) {
[email protected]dd2c4382013-09-07 16:01:471045 scoped_ptr<FileStream> stream(
1046 new FileStream(NULL, base::MessageLoopProxy::current()));
[email protected]dbb747c2012-02-29 19:29:471047 int flags = base::PLATFORM_FILE_OPEN |
1048 base::PLATFORM_FILE_WRITE |
1049 base::PLATFORM_FILE_ASYNC;
1050 TestCompletionCallback open_callback;
1051 int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
1052 EXPECT_EQ(ERR_IO_PENDING, rv);
1053
1054 // Delete the stream without waiting for the open operation to be
1055 // complete. Should be safe.
1056 stream.reset();
1057 // open_callback won't be called.
[email protected]dd2c4382013-09-07 16:01:471058 base::RunLoop().RunUntilIdle();
[email protected]dbb747c2012-02-29 19:29:471059 EXPECT_FALSE(open_callback.have_result());
1060}
1061
[email protected]bfb88ec2013-02-27 20:21:351062// Verify that async Write() errors are mapped correctly.
1063TEST_F(FileStreamTest, AsyncWriteError) {
[email protected]dd2c4382013-09-07 16:01:471064 scoped_ptr<FileStream> stream(
1065 new FileStream(NULL, base::MessageLoopProxy::current()));
[email protected]bfb88ec2013-02-27 20:21:351066 int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
1067 base::PLATFORM_FILE_WRITE |
1068 base::PLATFORM_FILE_ASYNC;
[email protected]bfb88ec2013-02-27 20:21:351069 TestCompletionCallback callback;
[email protected]66af1d62013-03-06 23:13:201070 int rv = stream->Open(temp_file_path(), flags, callback.callback());
1071 EXPECT_EQ(ERR_IO_PENDING, rv);
1072 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]bfb88ec2013-02-27 20:21:351073
1074 // Try passing NULL buffer to Write() and check that it fails.
1075 scoped_refptr<IOBuffer> buf = new WrappedIOBuffer(NULL);
[email protected]90499482013-06-01 00:39:501076 rv = stream->Write(buf.get(), 1, callback.callback());
[email protected]bfb88ec2013-02-27 20:21:351077 if (rv == ERR_IO_PENDING)
1078 rv = callback.WaitForResult();
1079 EXPECT_LT(rv, 0);
1080}
1081
1082// Verify that async Read() errors are mapped correctly.
1083TEST_F(FileStreamTest, AsyncReadError) {
[email protected]dd2c4382013-09-07 16:01:471084 scoped_ptr<FileStream> stream(
1085 new FileStream(NULL, base::MessageLoopProxy::current()));
[email protected]bfb88ec2013-02-27 20:21:351086 int flags = base::PLATFORM_FILE_OPEN |
1087 base::PLATFORM_FILE_READ |
1088 base::PLATFORM_FILE_ASYNC;
[email protected]bfb88ec2013-02-27 20:21:351089 TestCompletionCallback callback;
[email protected]66af1d62013-03-06 23:13:201090 int rv = stream->Open(temp_file_path(), flags, callback.callback());
1091 EXPECT_EQ(ERR_IO_PENDING, rv);
1092 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]bfb88ec2013-02-27 20:21:351093
1094 // Try passing NULL buffer to Read() and check that it fails.
1095 scoped_refptr<IOBuffer> buf = new WrappedIOBuffer(NULL);
[email protected]90499482013-06-01 00:39:501096 rv = stream->Read(buf.get(), 1, callback.callback());
[email protected]bfb88ec2013-02-27 20:21:351097 if (rv == ERR_IO_PENDING)
1098 rv = callback.WaitForResult();
1099 EXPECT_LT(rv, 0);
1100}
1101
[email protected]4c2048a2009-03-24 21:02:011102} // namespace
[email protected]96d73822011-10-10 02:11:241103
[email protected]8effd3f62011-03-25 16:29:071104} // namespace net