blob: a091e7a42aab291ded75234a57a9945a0f5e8220 [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]21da6eb2008-11-03 17:18:1411#include "base/path_service.h"
[email protected]92aad5222009-02-09 22:26:4112#include "base/platform_file.h"
[email protected]e3d66fde2012-02-17 22:10:3413#include "base/synchronization/waitable_event.h"
14#include "base/test/test_timeouts.h"
15#include "net/base/capturing_net_log.h"
[email protected]9f49afb2012-02-16 09:59:2016#include "net/base/io_buffer.h"
[email protected]21da6eb2008-11-03 17:18:1417#include "net/base/net_errors.h"
18#include "net/base/test_completion_callback.h"
19#include "testing/gtest/include/gtest/gtest.h"
[email protected]23887f04f2008-12-02 19:20:1520#include "testing/platform_test.h"
[email protected]21da6eb2008-11-03 17:18:1421
[email protected]8effd3f62011-03-25 16:29:0722namespace net {
[email protected]96d73822011-10-10 02:11:2423
[email protected]4c2048a2009-03-24 21:02:0124namespace {
25
26const char kTestData[] = "0123456789";
27const int kTestDataSize = arraysize(kTestData) - 1;
[email protected]21da6eb2008-11-03 17:18:1428
[email protected]9f49afb2012-02-16 09:59:2029// Creates an IOBufferWithSize that contains the kTestDataSize.
30IOBufferWithSize* CreateTestDataBuffer() {
31 IOBufferWithSize* buf = new IOBufferWithSize(kTestDataSize);
32 memcpy(buf->data(), kTestData, kTestDataSize);
33 return buf;
34}
35
[email protected]96d73822011-10-10 02:11:2436} // namespace
37
[email protected]21da6eb2008-11-03 17:18:1438class FileStreamTest : public PlatformTest {
39 public:
40 virtual void SetUp() {
41 PlatformTest::SetUp();
42
[email protected]33edeab2009-08-18 16:07:5543 file_util::CreateTemporaryFile(&temp_file_path_);
[email protected]7ff3f632009-10-13 18:43:3544 file_util::WriteFile(temp_file_path_, kTestData, kTestDataSize);
[email protected]21da6eb2008-11-03 17:18:1445 }
46 virtual void TearDown() {
[email protected]dd3aa792013-07-16 19:10:2347 EXPECT_TRUE(base::DeleteFile(temp_file_path_, false));
[email protected]21da6eb2008-11-03 17:18:1448
49 PlatformTest::TearDown();
50 }
[email protected]96d73822011-10-10 02:11:2451
[email protected]6cdfd7f2013-02-08 20:40:1552 const base::FilePath temp_file_path() const { return temp_file_path_; }
[email protected]96d73822011-10-10 02:11:2453
[email protected]21da6eb2008-11-03 17:18:1454 private:
[email protected]6cdfd7f2013-02-08 20:40:1555 base::FilePath temp_file_path_;
[email protected]21da6eb2008-11-03 17:18:1456};
57
[email protected]96d73822011-10-10 02:11:2458namespace {
59
[email protected]21da6eb2008-11-03 17:18:1460TEST_F(FileStreamTest, BasicOpenClose) {
[email protected]96d73822011-10-10 02:11:2461 base::PlatformFile file = base::kInvalidPlatformFileValue;
62 {
[email protected]10342992012-02-02 18:49:4363 FileStream stream(NULL);
[email protected]fe57eb22012-02-09 05:59:4064 int rv = stream.OpenSync(temp_file_path(),
[email protected]96d73822011-10-10 02:11:2465 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ);
66 EXPECT_EQ(OK, rv);
67 EXPECT_TRUE(stream.IsOpen());
[email protected]84e0309f2012-02-24 01:56:5968 file = stream.GetPlatformFileForTesting();
[email protected]96d73822011-10-10 02:11:2469 }
70 EXPECT_NE(base::kInvalidPlatformFileValue, file);
71 base::PlatformFileInfo info;
72 // The file should be closed.
73 EXPECT_FALSE(base::GetPlatformFileInfo(file, &info));
74}
75
[email protected]aab1b9e2012-11-06 00:29:5176TEST_F(FileStreamTest, FileHandleNotLeftOpen) {
[email protected]96d73822011-10-10 02:11:2477 bool created = false;
78 ASSERT_EQ(kTestDataSize,
79 file_util::WriteFile(temp_file_path(), kTestData, kTestDataSize));
80 int flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_READ;
81 base::PlatformFile file = base::CreatePlatformFile(
82 temp_file_path(), flags, &created, NULL);
83
84 {
85 // Seek to the beginning of the file and read.
[email protected]10342992012-02-02 18:49:4386 FileStream read_stream(file, flags, NULL);
[email protected]96d73822011-10-10 02:11:2487 EXPECT_TRUE(read_stream.IsOpen());
88 }
89
90 EXPECT_NE(base::kInvalidPlatformFileValue, file);
91 base::PlatformFileInfo info;
[email protected]aab1b9e2012-11-06 00:29:5192 // The file should be closed.
93 EXPECT_FALSE(base::GetPlatformFileInfo(file, &info));
[email protected]21da6eb2008-11-03 17:18:1494}
95
[email protected]92aad5222009-02-09 22:26:4196// Test the use of FileStream with a file handle provided at construction.
97TEST_F(FileStreamTest, UseFileHandle) {
98 bool created = false;
99
100 // 1. Test reading with a file handle.
101 ASSERT_EQ(kTestDataSize,
102 file_util::WriteFile(temp_file_path(), kTestData, kTestDataSize));
103 int flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_READ;
104 base::PlatformFile file = base::CreatePlatformFile(
[email protected]ed65fec2010-08-31 19:30:27105 temp_file_path(), flags, &created, NULL);
[email protected]92aad5222009-02-09 22:26:41106
107 // Seek to the beginning of the file and read.
[email protected]aab1b9e2012-11-06 00:29:51108 scoped_ptr<FileStream> read_stream(new FileStream(file, flags, NULL));
109 ASSERT_EQ(0, read_stream->SeekSync(FROM_BEGIN, 0));
110 ASSERT_EQ(kTestDataSize, read_stream->Available());
[email protected]92aad5222009-02-09 22:26:41111 // Read into buffer and compare.
112 char buffer[kTestDataSize];
[email protected]5eb431e22011-10-12 08:51:38113 ASSERT_EQ(kTestDataSize,
[email protected]aab1b9e2012-11-06 00:29:51114 read_stream->ReadSync(buffer, kTestDataSize));
[email protected]92aad5222009-02-09 22:26:41115 ASSERT_EQ(0, memcmp(kTestData, buffer, kTestDataSize));
[email protected]aab1b9e2012-11-06 00:29:51116 read_stream.reset();
[email protected]92aad5222009-02-09 22:26:41117
118 // 2. Test writing with a file handle.
[email protected]dd3aa792013-07-16 19:10:23119 base::DeleteFile(temp_file_path(), false);
[email protected]92aad5222009-02-09 22:26:41120 flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_WRITE;
[email protected]ed65fec2010-08-31 19:30:27121 file = base::CreatePlatformFile(temp_file_path(), flags, &created, NULL);
[email protected]92aad5222009-02-09 22:26:41122
[email protected]aab1b9e2012-11-06 00:29:51123 scoped_ptr<FileStream> write_stream(new FileStream(file, flags, NULL));
124 ASSERT_EQ(0, write_stream->SeekSync(FROM_BEGIN, 0));
[email protected]5eb431e22011-10-12 08:51:38125 ASSERT_EQ(kTestDataSize,
[email protected]aab1b9e2012-11-06 00:29:51126 write_stream->WriteSync(kTestData, kTestDataSize));
127 write_stream.reset();
[email protected]92aad5222009-02-09 22:26:41128
129 // Read into buffer and compare to make sure the handle worked fine.
130 ASSERT_EQ(kTestDataSize,
131 file_util::ReadFile(temp_file_path(), buffer, kTestDataSize));
132 ASSERT_EQ(0, memcmp(kTestData, buffer, kTestDataSize));
133}
134
[email protected]21da6eb2008-11-03 17:18:14135TEST_F(FileStreamTest, UseClosedStream) {
[email protected]10342992012-02-02 18:49:43136 FileStream stream(NULL);
[email protected]21da6eb2008-11-03 17:18:14137
138 EXPECT_FALSE(stream.IsOpen());
139
140 // Try seeking...
[email protected]cf02541b2012-04-11 08:02:17141 int64 new_offset = stream.SeekSync(FROM_BEGIN, 5);
[email protected]8effd3f62011-03-25 16:29:07142 EXPECT_EQ(ERR_UNEXPECTED, new_offset);
[email protected]21da6eb2008-11-03 17:18:14143
144 // Try available...
145 int64 avail = stream.Available();
[email protected]8effd3f62011-03-25 16:29:07146 EXPECT_EQ(ERR_UNEXPECTED, avail);
[email protected]21da6eb2008-11-03 17:18:14147
148 // Try reading...
149 char buf[10];
[email protected]6b230f42012-02-15 04:08:41150 int rv = stream.ReadSync(buf, arraysize(buf));
[email protected]8effd3f62011-03-25 16:29:07151 EXPECT_EQ(ERR_UNEXPECTED, rv);
[email protected]21da6eb2008-11-03 17:18:14152}
153
154TEST_F(FileStreamTest, BasicRead) {
155 int64 file_size;
156 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
157 EXPECT_TRUE(ok);
158
[email protected]10342992012-02-02 18:49:43159 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38160 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14161 base::PLATFORM_FILE_READ;
[email protected]fe57eb22012-02-09 05:59:40162 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07163 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14164
165 int64 total_bytes_avail = stream.Available();
166 EXPECT_EQ(file_size, total_bytes_avail);
167
[email protected]4c2048a2009-03-24 21:02:01168 int total_bytes_read = 0;
[email protected]21da6eb2008-11-03 17:18:14169
170 std::string data_read;
171 for (;;) {
172 char buf[4];
[email protected]6b230f42012-02-15 04:08:41173 rv = stream.ReadSync(buf, arraysize(buf));
[email protected]21da6eb2008-11-03 17:18:14174 EXPECT_LE(0, rv);
175 if (rv <= 0)
176 break;
177 total_bytes_read += rv;
178 data_read.append(buf, rv);
179 }
180 EXPECT_EQ(file_size, total_bytes_read);
[email protected]4c2048a2009-03-24 21:02:01181 EXPECT_EQ(kTestData, data_read);
[email protected]21da6eb2008-11-03 17:18:14182}
183
184TEST_F(FileStreamTest, AsyncRead) {
185 int64 file_size;
186 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
187 EXPECT_TRUE(ok);
188
[email protected]10342992012-02-02 18:49:43189 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38190 int flags = base::PLATFORM_FILE_OPEN |
191 base::PLATFORM_FILE_READ |
[email protected]21da6eb2008-11-03 17:18:14192 base::PLATFORM_FILE_ASYNC;
[email protected]66af1d62013-03-06 23:13:20193 TestCompletionCallback callback;
194 int rv = stream.Open(temp_file_path(), flags, callback.callback());
195 EXPECT_EQ(ERR_IO_PENDING, rv);
196 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]21da6eb2008-11-03 17:18:14197
198 int64 total_bytes_avail = stream.Available();
199 EXPECT_EQ(file_size, total_bytes_avail);
200
[email protected]4c2048a2009-03-24 21:02:01201 int total_bytes_read = 0;
[email protected]21da6eb2008-11-03 17:18:14202
203 std::string data_read;
204 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20205 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
[email protected]90499482013-06-01 00:39:50206 rv = stream.Read(buf.get(), buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07207 if (rv == ERR_IO_PENDING)
[email protected]21da6eb2008-11-03 17:18:14208 rv = callback.WaitForResult();
209 EXPECT_LE(0, rv);
210 if (rv <= 0)
211 break;
212 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20213 data_read.append(buf->data(), rv);
[email protected]21da6eb2008-11-03 17:18:14214 }
215 EXPECT_EQ(file_size, total_bytes_read);
[email protected]4c2048a2009-03-24 21:02:01216 EXPECT_EQ(kTestData, data_read);
217}
218
[email protected]06b802b2012-02-22 03:34:54219TEST_F(FileStreamTest, AsyncRead_EarlyDelete) {
220 int64 file_size;
221 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
222 EXPECT_TRUE(ok);
223
224 scoped_ptr<FileStream> stream(new FileStream(NULL));
225 int flags = base::PLATFORM_FILE_OPEN |
226 base::PLATFORM_FILE_READ |
227 base::PLATFORM_FILE_ASYNC;
228 TestCompletionCallback callback;
229 int rv = stream->Open(temp_file_path(), flags, callback.callback());
230 EXPECT_EQ(ERR_IO_PENDING, rv);
231 EXPECT_EQ(OK, callback.WaitForResult());
232
233 int64 total_bytes_avail = stream->Available();
234 EXPECT_EQ(file_size, total_bytes_avail);
235
236 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
[email protected]90499482013-06-01 00:39:50237 rv = stream->Read(buf.get(), buf->size(), callback.callback());
[email protected]06b802b2012-02-22 03:34:54238 stream.reset(); // Delete instead of closing it.
239 if (rv < 0) {
240 EXPECT_EQ(ERR_IO_PENDING, rv);
241 // The callback should not be called if the request is cancelled.
[email protected]2da659e2013-05-23 20:51:34242 base::MessageLoop::current()->RunUntilIdle();
[email protected]06b802b2012-02-22 03:34:54243 EXPECT_FALSE(callback.have_result());
244 } else {
245 EXPECT_EQ(std::string(kTestData, rv), std::string(buf->data(), rv));
246 }
247}
248
[email protected]21da6eb2008-11-03 17:18:14249TEST_F(FileStreamTest, BasicRead_FromOffset) {
250 int64 file_size;
251 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
252 EXPECT_TRUE(ok);
253
[email protected]10342992012-02-02 18:49:43254 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38255 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14256 base::PLATFORM_FILE_READ;
[email protected]fe57eb22012-02-09 05:59:40257 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07258 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14259
260 const int64 kOffset = 3;
[email protected]cf02541b2012-04-11 08:02:17261 int64 new_offset = stream.SeekSync(FROM_BEGIN, kOffset);
[email protected]21da6eb2008-11-03 17:18:14262 EXPECT_EQ(kOffset, new_offset);
263
264 int64 total_bytes_avail = stream.Available();
265 EXPECT_EQ(file_size - kOffset, total_bytes_avail);
266
267 int64 total_bytes_read = 0;
268
269 std::string data_read;
270 for (;;) {
271 char buf[4];
[email protected]6b230f42012-02-15 04:08:41272 rv = stream.ReadSync(buf, arraysize(buf));
[email protected]21da6eb2008-11-03 17:18:14273 EXPECT_LE(0, rv);
274 if (rv <= 0)
275 break;
276 total_bytes_read += rv;
277 data_read.append(buf, rv);
278 }
279 EXPECT_EQ(file_size - kOffset, total_bytes_read);
280 EXPECT_TRUE(data_read == kTestData + kOffset);
[email protected]4c2048a2009-03-24 21:02:01281 EXPECT_EQ(kTestData + kOffset, data_read);
[email protected]21da6eb2008-11-03 17:18:14282}
283
284TEST_F(FileStreamTest, AsyncRead_FromOffset) {
285 int64 file_size;
286 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
287 EXPECT_TRUE(ok);
288
[email protected]10342992012-02-02 18:49:43289 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38290 int flags = base::PLATFORM_FILE_OPEN |
291 base::PLATFORM_FILE_READ |
[email protected]21da6eb2008-11-03 17:18:14292 base::PLATFORM_FILE_ASYNC;
[email protected]66af1d62013-03-06 23:13:20293 TestCompletionCallback callback;
294 int rv = stream.Open(temp_file_path(), flags, callback.callback());
295 EXPECT_EQ(ERR_IO_PENDING, rv);
296 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]21da6eb2008-11-03 17:18:14297
[email protected]cf02541b2012-04-11 08:02:17298 TestInt64CompletionCallback callback64;
[email protected]21da6eb2008-11-03 17:18:14299 const int64 kOffset = 3;
[email protected]cf02541b2012-04-11 08:02:17300 rv = stream.Seek(FROM_BEGIN, kOffset, callback64.callback());
301 ASSERT_EQ(ERR_IO_PENDING, rv);
302 int64 new_offset = callback64.WaitForResult();
[email protected]21da6eb2008-11-03 17:18:14303 EXPECT_EQ(kOffset, new_offset);
304
305 int64 total_bytes_avail = stream.Available();
306 EXPECT_EQ(file_size - kOffset, total_bytes_avail);
307
[email protected]4c2048a2009-03-24 21:02:01308 int total_bytes_read = 0;
[email protected]21da6eb2008-11-03 17:18:14309
310 std::string data_read;
311 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20312 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
[email protected]90499482013-06-01 00:39:50313 rv = stream.Read(buf.get(), buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07314 if (rv == ERR_IO_PENDING)
[email protected]21da6eb2008-11-03 17:18:14315 rv = callback.WaitForResult();
316 EXPECT_LE(0, rv);
317 if (rv <= 0)
318 break;
319 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20320 data_read.append(buf->data(), rv);
[email protected]21da6eb2008-11-03 17:18:14321 }
322 EXPECT_EQ(file_size - kOffset, total_bytes_read);
[email protected]4c2048a2009-03-24 21:02:01323 EXPECT_EQ(kTestData + kOffset, data_read);
[email protected]21da6eb2008-11-03 17:18:14324}
325
326TEST_F(FileStreamTest, SeekAround) {
[email protected]10342992012-02-02 18:49:43327 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38328 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14329 base::PLATFORM_FILE_READ;
[email protected]fe57eb22012-02-09 05:59:40330 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07331 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14332
333 const int64 kOffset = 3;
[email protected]cf02541b2012-04-11 08:02:17334 int64 new_offset = stream.SeekSync(FROM_BEGIN, kOffset);
[email protected]21da6eb2008-11-03 17:18:14335 EXPECT_EQ(kOffset, new_offset);
336
[email protected]cf02541b2012-04-11 08:02:17337 new_offset = stream.SeekSync(FROM_CURRENT, kOffset);
[email protected]21da6eb2008-11-03 17:18:14338 EXPECT_EQ(2 * kOffset, new_offset);
339
[email protected]cf02541b2012-04-11 08:02:17340 new_offset = stream.SeekSync(FROM_CURRENT, -kOffset);
[email protected]21da6eb2008-11-03 17:18:14341 EXPECT_EQ(kOffset, new_offset);
342
343 const int kTestDataLen = arraysize(kTestData) - 1;
344
[email protected]cf02541b2012-04-11 08:02:17345 new_offset = stream.SeekSync(FROM_END, -kTestDataLen);
346 EXPECT_EQ(0, new_offset);
347}
348
349TEST_F(FileStreamTest, AsyncSeekAround) {
350 FileStream stream(NULL);
351 int flags = base::PLATFORM_FILE_OPEN |
352 base::PLATFORM_FILE_ASYNC |
353 base::PLATFORM_FILE_READ;
[email protected]66af1d62013-03-06 23:13:20354 TestCompletionCallback callback;
355 int rv = stream.Open(temp_file_path(), flags, callback.callback());
356 EXPECT_EQ(ERR_IO_PENDING, rv);
357 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]cf02541b2012-04-11 08:02:17358
[email protected]66af1d62013-03-06 23:13:20359 TestInt64CompletionCallback callback64;
[email protected]cf02541b2012-04-11 08:02:17360
361 const int64 kOffset = 3;
[email protected]66af1d62013-03-06 23:13:20362 rv = stream.Seek(FROM_BEGIN, kOffset, callback64.callback());
[email protected]cf02541b2012-04-11 08:02:17363 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]66af1d62013-03-06 23:13:20364 int64 new_offset = callback64.WaitForResult();
[email protected]cf02541b2012-04-11 08:02:17365 EXPECT_EQ(kOffset, new_offset);
366
[email protected]66af1d62013-03-06 23:13:20367 rv = stream.Seek(FROM_CURRENT, kOffset, callback64.callback());
[email protected]cf02541b2012-04-11 08:02:17368 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]66af1d62013-03-06 23:13:20369 new_offset = callback64.WaitForResult();
[email protected]cf02541b2012-04-11 08:02:17370 EXPECT_EQ(2 * kOffset, new_offset);
371
[email protected]66af1d62013-03-06 23:13:20372 rv = stream.Seek(FROM_CURRENT, -kOffset, callback64.callback());
[email protected]cf02541b2012-04-11 08:02:17373 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]66af1d62013-03-06 23:13:20374 new_offset = callback64.WaitForResult();
[email protected]cf02541b2012-04-11 08:02:17375 EXPECT_EQ(kOffset, new_offset);
376
377 const int kTestDataLen = arraysize(kTestData) - 1;
378
[email protected]66af1d62013-03-06 23:13:20379 rv = stream.Seek(FROM_END, -kTestDataLen, callback64.callback());
[email protected]cf02541b2012-04-11 08:02:17380 ASSERT_EQ(ERR_IO_PENDING, rv);
[email protected]66af1d62013-03-06 23:13:20381 new_offset = callback64.WaitForResult();
[email protected]21da6eb2008-11-03 17:18:14382 EXPECT_EQ(0, new_offset);
383}
384
385TEST_F(FileStreamTest, BasicWrite) {
[email protected]aab1b9e2012-11-06 00:29:51386 scoped_ptr<FileStream> stream(new FileStream(NULL));
[email protected]f0a51fb52009-03-05 12:46:38387 int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
[email protected]21da6eb2008-11-03 17:18:14388 base::PLATFORM_FILE_WRITE;
[email protected]aab1b9e2012-11-06 00:29:51389 int rv = stream->OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07390 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14391
392 int64 file_size;
393 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
394 EXPECT_TRUE(ok);
395 EXPECT_EQ(0, file_size);
396
[email protected]aab1b9e2012-11-06 00:29:51397 rv = stream->WriteSync(kTestData, kTestDataSize);
[email protected]21da6eb2008-11-03 17:18:14398 EXPECT_EQ(kTestDataSize, rv);
[email protected]aab1b9e2012-11-06 00:29:51399 stream.reset();
[email protected]21da6eb2008-11-03 17:18:14400
401 ok = file_util::GetFileSize(temp_file_path(), &file_size);
402 EXPECT_TRUE(ok);
403 EXPECT_EQ(kTestDataSize, file_size);
404}
405
406TEST_F(FileStreamTest, AsyncWrite) {
[email protected]10342992012-02-02 18:49:43407 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38408 int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
409 base::PLATFORM_FILE_WRITE |
[email protected]21da6eb2008-11-03 17:18:14410 base::PLATFORM_FILE_ASYNC;
[email protected]66af1d62013-03-06 23:13:20411 TestCompletionCallback callback;
412 int rv = stream.Open(temp_file_path(), flags, callback.callback());
413 EXPECT_EQ(ERR_IO_PENDING, rv);
414 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]21da6eb2008-11-03 17:18:14415
416 int64 file_size;
417 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
418 EXPECT_TRUE(ok);
419 EXPECT_EQ(0, file_size);
420
[email protected]4c2048a2009-03-24 21:02:01421 int total_bytes_written = 0;
[email protected]21da6eb2008-11-03 17:18:14422
[email protected]9f49afb2012-02-16 09:59:20423 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
424 scoped_refptr<DrainableIOBuffer> drainable =
[email protected]90499482013-06-01 00:39:50425 new DrainableIOBuffer(buf.get(), buf->size());
[email protected]21da6eb2008-11-03 17:18:14426 while (total_bytes_written != kTestDataSize) {
[email protected]90499482013-06-01 00:39:50427 rv = stream.Write(
428 drainable.get(), drainable->BytesRemaining(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07429 if (rv == ERR_IO_PENDING)
[email protected]21da6eb2008-11-03 17:18:14430 rv = callback.WaitForResult();
431 EXPECT_LT(0, rv);
432 if (rv <= 0)
433 break;
[email protected]9f49afb2012-02-16 09:59:20434 drainable->DidConsume(rv);
[email protected]21da6eb2008-11-03 17:18:14435 total_bytes_written += rv;
436 }
437 ok = file_util::GetFileSize(temp_file_path(), &file_size);
438 EXPECT_TRUE(ok);
439 EXPECT_EQ(file_size, total_bytes_written);
440}
441
[email protected]aab1b9e2012-11-06 00:29:51442TEST_F(FileStreamTest, AsyncWrite_EarlyDelete) {
443 scoped_ptr<FileStream> stream(new FileStream(NULL));
[email protected]4c2048a2009-03-24 21:02:01444 int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
445 base::PLATFORM_FILE_WRITE |
446 base::PLATFORM_FILE_ASYNC;
[email protected]66af1d62013-03-06 23:13:20447 TestCompletionCallback callback;
448 int rv = stream->Open(temp_file_path(), flags, callback.callback());
449 EXPECT_EQ(ERR_IO_PENDING, rv);
450 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]4c2048a2009-03-24 21:02:01451
452 int64 file_size;
453 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
454 EXPECT_TRUE(ok);
455 EXPECT_EQ(0, file_size);
456
[email protected]9f49afb2012-02-16 09:59:20457 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
[email protected]90499482013-06-01 00:39:50458 rv = stream->Write(buf.get(), buf->size(), callback.callback());
[email protected]aab1b9e2012-11-06 00:29:51459 stream.reset();
[email protected]3828a752009-06-03 23:05:59460 if (rv < 0) {
[email protected]8effd3f62011-03-25 16:29:07461 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3828a752009-06-03 23:05:59462 // The callback should not be called if the request is cancelled.
[email protected]2da659e2013-05-23 20:51:34463 base::MessageLoop::current()->RunUntilIdle();
[email protected]3828a752009-06-03 23:05:59464 EXPECT_FALSE(callback.have_result());
465 } else {
466 ok = file_util::GetFileSize(temp_file_path(), &file_size);
467 EXPECT_TRUE(ok);
468 EXPECT_EQ(file_size, rv);
469 }
[email protected]4c2048a2009-03-24 21:02:01470}
471
[email protected]21da6eb2008-11-03 17:18:14472TEST_F(FileStreamTest, BasicWrite_FromOffset) {
[email protected]aab1b9e2012-11-06 00:29:51473 scoped_ptr<FileStream> stream(new FileStream(NULL));
[email protected]f0a51fb52009-03-05 12:46:38474 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14475 base::PLATFORM_FILE_WRITE;
[email protected]aab1b9e2012-11-06 00:29:51476 int rv = stream->OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07477 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14478
479 int64 file_size;
480 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
481 EXPECT_TRUE(ok);
482 EXPECT_EQ(kTestDataSize, file_size);
483
484 const int64 kOffset = 0;
[email protected]aab1b9e2012-11-06 00:29:51485 int64 new_offset = stream->SeekSync(FROM_END, kOffset);
[email protected]21da6eb2008-11-03 17:18:14486 EXPECT_EQ(kTestDataSize, new_offset);
487
[email protected]aab1b9e2012-11-06 00:29:51488 rv = stream->WriteSync(kTestData, kTestDataSize);
[email protected]21da6eb2008-11-03 17:18:14489 EXPECT_EQ(kTestDataSize, rv);
[email protected]aab1b9e2012-11-06 00:29:51490 stream.reset();
[email protected]21da6eb2008-11-03 17:18:14491
492 ok = file_util::GetFileSize(temp_file_path(), &file_size);
493 EXPECT_TRUE(ok);
494 EXPECT_EQ(kTestDataSize * 2, file_size);
495}
496
497TEST_F(FileStreamTest, AsyncWrite_FromOffset) {
498 int64 file_size;
499 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
500 EXPECT_TRUE(ok);
501
[email protected]10342992012-02-02 18:49:43502 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38503 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14504 base::PLATFORM_FILE_WRITE |
505 base::PLATFORM_FILE_ASYNC;
[email protected]66af1d62013-03-06 23:13:20506 TestCompletionCallback callback;
507 int rv = stream.Open(temp_file_path(), flags, callback.callback());
508 EXPECT_EQ(ERR_IO_PENDING, rv);
509 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]21da6eb2008-11-03 17:18:14510
[email protected]cf02541b2012-04-11 08:02:17511 TestInt64CompletionCallback callback64;
[email protected]21da6eb2008-11-03 17:18:14512 const int64 kOffset = 0;
[email protected]cf02541b2012-04-11 08:02:17513 rv = stream.Seek(FROM_END, kOffset, callback64.callback());
514 ASSERT_EQ(ERR_IO_PENDING, rv);
515 int64 new_offset = callback64.WaitForResult();
[email protected]21da6eb2008-11-03 17:18:14516 EXPECT_EQ(kTestDataSize, new_offset);
517
[email protected]4c2048a2009-03-24 21:02:01518 int total_bytes_written = 0;
[email protected]21da6eb2008-11-03 17:18:14519
[email protected]9f49afb2012-02-16 09:59:20520 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
521 scoped_refptr<DrainableIOBuffer> drainable =
[email protected]90499482013-06-01 00:39:50522 new DrainableIOBuffer(buf.get(), buf->size());
[email protected]21da6eb2008-11-03 17:18:14523 while (total_bytes_written != kTestDataSize) {
[email protected]90499482013-06-01 00:39:50524 rv = stream.Write(
525 drainable.get(), drainable->BytesRemaining(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07526 if (rv == ERR_IO_PENDING)
[email protected]21da6eb2008-11-03 17:18:14527 rv = callback.WaitForResult();
528 EXPECT_LT(0, rv);
529 if (rv <= 0)
530 break;
[email protected]9f49afb2012-02-16 09:59:20531 drainable->DidConsume(rv);
[email protected]21da6eb2008-11-03 17:18:14532 total_bytes_written += rv;
533 }
534 ok = file_util::GetFileSize(temp_file_path(), &file_size);
535 EXPECT_TRUE(ok);
536 EXPECT_EQ(file_size, kTestDataSize * 2);
537}
538
539TEST_F(FileStreamTest, BasicReadWrite) {
540 int64 file_size;
541 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
542 EXPECT_TRUE(ok);
543
[email protected]aab1b9e2012-11-06 00:29:51544 scoped_ptr<FileStream> stream(new FileStream(NULL));
[email protected]f0a51fb52009-03-05 12:46:38545 int flags = base::PLATFORM_FILE_OPEN |
546 base::PLATFORM_FILE_READ |
[email protected]21da6eb2008-11-03 17:18:14547 base::PLATFORM_FILE_WRITE;
[email protected]aab1b9e2012-11-06 00:29:51548 int rv = stream->OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07549 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14550
[email protected]aab1b9e2012-11-06 00:29:51551 int64 total_bytes_avail = stream->Available();
[email protected]21da6eb2008-11-03 17:18:14552 EXPECT_EQ(file_size, total_bytes_avail);
553
[email protected]4c2048a2009-03-24 21:02:01554 int total_bytes_read = 0;
[email protected]21da6eb2008-11-03 17:18:14555
556 std::string data_read;
557 for (;;) {
558 char buf[4];
[email protected]aab1b9e2012-11-06 00:29:51559 rv = stream->ReadSync(buf, arraysize(buf));
[email protected]21da6eb2008-11-03 17:18:14560 EXPECT_LE(0, rv);
561 if (rv <= 0)
562 break;
563 total_bytes_read += rv;
564 data_read.append(buf, rv);
565 }
566 EXPECT_EQ(file_size, total_bytes_read);
567 EXPECT_TRUE(data_read == kTestData);
568
[email protected]aab1b9e2012-11-06 00:29:51569 rv = stream->WriteSync(kTestData, kTestDataSize);
[email protected]21da6eb2008-11-03 17:18:14570 EXPECT_EQ(kTestDataSize, rv);
[email protected]aab1b9e2012-11-06 00:29:51571 stream.reset();
[email protected]21da6eb2008-11-03 17:18:14572
573 ok = file_util::GetFileSize(temp_file_path(), &file_size);
574 EXPECT_TRUE(ok);
575 EXPECT_EQ(kTestDataSize * 2, file_size);
576}
577
[email protected]4c2048a2009-03-24 21:02:01578TEST_F(FileStreamTest, BasicWriteRead) {
579 int64 file_size;
580 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
581 EXPECT_TRUE(ok);
582
[email protected]aab1b9e2012-11-06 00:29:51583 scoped_ptr<FileStream> stream(new FileStream(NULL));
[email protected]4c2048a2009-03-24 21:02:01584 int flags = base::PLATFORM_FILE_OPEN |
585 base::PLATFORM_FILE_READ |
586 base::PLATFORM_FILE_WRITE;
[email protected]aab1b9e2012-11-06 00:29:51587 int rv = stream->OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07588 EXPECT_EQ(OK, rv);
[email protected]4c2048a2009-03-24 21:02:01589
[email protected]aab1b9e2012-11-06 00:29:51590 int64 total_bytes_avail = stream->Available();
[email protected]4c2048a2009-03-24 21:02:01591 EXPECT_EQ(file_size, total_bytes_avail);
592
[email protected]aab1b9e2012-11-06 00:29:51593 int64 offset = stream->SeekSync(FROM_END, 0);
[email protected]4c2048a2009-03-24 21:02:01594 EXPECT_EQ(offset, file_size);
595
[email protected]aab1b9e2012-11-06 00:29:51596 rv = stream->WriteSync(kTestData, kTestDataSize);
[email protected]4c2048a2009-03-24 21:02:01597 EXPECT_EQ(kTestDataSize, rv);
598
[email protected]aab1b9e2012-11-06 00:29:51599 offset = stream->SeekSync(FROM_BEGIN, 0);
[email protected]4c2048a2009-03-24 21:02:01600 EXPECT_EQ(0, offset);
601
602 int64 total_bytes_read = 0;
603
604 std::string data_read;
605 for (;;) {
606 char buf[4];
[email protected]aab1b9e2012-11-06 00:29:51607 rv = stream->ReadSync(buf, arraysize(buf));
[email protected]4c2048a2009-03-24 21:02:01608 EXPECT_LE(0, rv);
609 if (rv <= 0)
610 break;
611 total_bytes_read += rv;
612 data_read.append(buf, rv);
613 }
[email protected]aab1b9e2012-11-06 00:29:51614 stream.reset();
[email protected]4c2048a2009-03-24 21:02:01615
616 ok = file_util::GetFileSize(temp_file_path(), &file_size);
617 EXPECT_TRUE(ok);
618 EXPECT_EQ(kTestDataSize * 2, file_size);
619 EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
620
621 const std::string kExpectedFileData =
622 std::string(kTestData) + std::string(kTestData);
623 EXPECT_EQ(kExpectedFileData, data_read);
624}
625
626TEST_F(FileStreamTest, BasicAsyncReadWrite) {
627 int64 file_size;
628 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
629 EXPECT_TRUE(ok);
630
[email protected]aab1b9e2012-11-06 00:29:51631 scoped_ptr<FileStream> stream(new FileStream(NULL));
[email protected]4c2048a2009-03-24 21:02:01632 int flags = base::PLATFORM_FILE_OPEN |
633 base::PLATFORM_FILE_READ |
634 base::PLATFORM_FILE_WRITE |
635 base::PLATFORM_FILE_ASYNC;
[email protected]66af1d62013-03-06 23:13:20636 TestCompletionCallback callback;
637 int rv = stream->Open(temp_file_path(), flags, callback.callback());
638 EXPECT_EQ(ERR_IO_PENDING, rv);
639 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]4c2048a2009-03-24 21:02:01640
[email protected]aab1b9e2012-11-06 00:29:51641 int64 total_bytes_avail = stream->Available();
[email protected]4c2048a2009-03-24 21:02:01642 EXPECT_EQ(file_size, total_bytes_avail);
643
[email protected]4c2048a2009-03-24 21:02:01644 int64 total_bytes_read = 0;
645
646 std::string data_read;
647 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20648 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
[email protected]90499482013-06-01 00:39:50649 rv = stream->Read(buf.get(), buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07650 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01651 rv = callback.WaitForResult();
652 EXPECT_LE(0, rv);
653 if (rv <= 0)
654 break;
655 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20656 data_read.append(buf->data(), rv);
[email protected]4c2048a2009-03-24 21:02:01657 }
658 EXPECT_EQ(file_size, total_bytes_read);
659 EXPECT_TRUE(data_read == kTestData);
660
661 int total_bytes_written = 0;
662
[email protected]9f49afb2012-02-16 09:59:20663 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
664 scoped_refptr<DrainableIOBuffer> drainable =
[email protected]90499482013-06-01 00:39:50665 new DrainableIOBuffer(buf.get(), buf->size());
[email protected]4c2048a2009-03-24 21:02:01666 while (total_bytes_written != kTestDataSize) {
[email protected]90499482013-06-01 00:39:50667 rv = stream->Write(
668 drainable.get(), drainable->BytesRemaining(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07669 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01670 rv = callback.WaitForResult();
671 EXPECT_LT(0, rv);
672 if (rv <= 0)
673 break;
[email protected]9f49afb2012-02-16 09:59:20674 drainable->DidConsume(rv);
[email protected]4c2048a2009-03-24 21:02:01675 total_bytes_written += rv;
676 }
677
[email protected]aab1b9e2012-11-06 00:29:51678 stream.reset();
[email protected]4c2048a2009-03-24 21:02:01679
680 ok = file_util::GetFileSize(temp_file_path(), &file_size);
681 EXPECT_TRUE(ok);
682 EXPECT_EQ(kTestDataSize * 2, file_size);
683}
684
685TEST_F(FileStreamTest, BasicAsyncWriteRead) {
686 int64 file_size;
687 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
688 EXPECT_TRUE(ok);
689
[email protected]aab1b9e2012-11-06 00:29:51690 scoped_ptr<FileStream> stream(new FileStream(NULL));
[email protected]4c2048a2009-03-24 21:02:01691 int flags = base::PLATFORM_FILE_OPEN |
692 base::PLATFORM_FILE_READ |
693 base::PLATFORM_FILE_WRITE |
694 base::PLATFORM_FILE_ASYNC;
[email protected]66af1d62013-03-06 23:13:20695 TestCompletionCallback callback;
696 int rv = stream->Open(temp_file_path(), flags, callback.callback());
697 EXPECT_EQ(ERR_IO_PENDING, rv);
698 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]4c2048a2009-03-24 21:02:01699
[email protected]aab1b9e2012-11-06 00:29:51700 int64 total_bytes_avail = stream->Available();
[email protected]4c2048a2009-03-24 21:02:01701 EXPECT_EQ(file_size, total_bytes_avail);
702
[email protected]cf02541b2012-04-11 08:02:17703 TestInt64CompletionCallback callback64;
[email protected]aab1b9e2012-11-06 00:29:51704 rv = stream->Seek(FROM_END, 0, callback64.callback());
[email protected]cf02541b2012-04-11 08:02:17705 ASSERT_EQ(ERR_IO_PENDING, rv);
706 int64 offset = callback64.WaitForResult();
[email protected]4c2048a2009-03-24 21:02:01707 EXPECT_EQ(offset, file_size);
708
[email protected]4c2048a2009-03-24 21:02:01709 int total_bytes_written = 0;
710
[email protected]9f49afb2012-02-16 09:59:20711 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
712 scoped_refptr<DrainableIOBuffer> drainable =
[email protected]90499482013-06-01 00:39:50713 new DrainableIOBuffer(buf.get(), buf->size());
[email protected]4c2048a2009-03-24 21:02:01714 while (total_bytes_written != kTestDataSize) {
[email protected]90499482013-06-01 00:39:50715 rv = stream->Write(
716 drainable.get(), drainable->BytesRemaining(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07717 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01718 rv = callback.WaitForResult();
719 EXPECT_LT(0, rv);
720 if (rv <= 0)
721 break;
[email protected]9f49afb2012-02-16 09:59:20722 drainable->DidConsume(rv);
[email protected]4c2048a2009-03-24 21:02:01723 total_bytes_written += rv;
724 }
725
726 EXPECT_EQ(kTestDataSize, total_bytes_written);
727
[email protected]aab1b9e2012-11-06 00:29:51728 rv = stream->Seek(FROM_BEGIN, 0, callback64.callback());
[email protected]cf02541b2012-04-11 08:02:17729 ASSERT_EQ(ERR_IO_PENDING, rv);
730 offset = callback64.WaitForResult();
[email protected]4c2048a2009-03-24 21:02:01731 EXPECT_EQ(0, offset);
732
733 int total_bytes_read = 0;
734
735 std::string data_read;
736 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20737 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
[email protected]90499482013-06-01 00:39:50738 rv = stream->Read(buf.get(), buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07739 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01740 rv = callback.WaitForResult();
741 EXPECT_LE(0, rv);
742 if (rv <= 0)
743 break;
744 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20745 data_read.append(buf->data(), rv);
[email protected]4c2048a2009-03-24 21:02:01746 }
[email protected]aab1b9e2012-11-06 00:29:51747 stream.reset();
[email protected]4c2048a2009-03-24 21:02:01748
749 ok = file_util::GetFileSize(temp_file_path(), &file_size);
750 EXPECT_TRUE(ok);
751 EXPECT_EQ(kTestDataSize * 2, file_size);
752
753 EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
754 const std::string kExpectedFileData =
755 std::string(kTestData) + std::string(kTestData);
756 EXPECT_EQ(kExpectedFileData, data_read);
757}
758
[email protected]5eb431e22011-10-12 08:51:38759class TestWriteReadCompletionCallback {
[email protected]4c2048a2009-03-24 21:02:01760 public:
[email protected]90499482013-06-01 00:39:50761 TestWriteReadCompletionCallback(FileStream* stream,
762 int* total_bytes_written,
763 int* total_bytes_read,
764 std::string* data_read)
[email protected]4c2048a2009-03-24 21:02:01765 : result_(0),
766 have_result_(false),
767 waiting_for_result_(false),
768 stream_(stream),
769 total_bytes_written_(total_bytes_written),
770 total_bytes_read_(total_bytes_read),
[email protected]5eb431e22011-10-12 08:51:38771 data_read_(data_read),
772 callback_(base::Bind(&TestWriteReadCompletionCallback::OnComplete,
[email protected]9f49afb2012-02-16 09:59:20773 base::Unretained(this))),
774 test_data_(CreateTestDataBuffer()),
[email protected]90499482013-06-01 00:39:50775 drainable_(new DrainableIOBuffer(test_data_.get(), kTestDataSize)) {}
[email protected]4c2048a2009-03-24 21:02:01776
777 int WaitForResult() {
778 DCHECK(!waiting_for_result_);
779 while (!have_result_) {
780 waiting_for_result_ = true;
[email protected]2da659e2013-05-23 20:51:34781 base::MessageLoop::current()->Run();
[email protected]4c2048a2009-03-24 21:02:01782 waiting_for_result_ = false;
783 }
784 have_result_ = false; // auto-reset for next callback
785 return result_;
786 }
787
[email protected]5eb431e22011-10-12 08:51:38788 const CompletionCallback& callback() const { return callback_; }
789
[email protected]4c2048a2009-03-24 21:02:01790 private:
[email protected]5eb431e22011-10-12 08:51:38791 void OnComplete(int result) {
792 DCHECK_LT(0, result);
793 *total_bytes_written_ += result;
[email protected]4c2048a2009-03-24 21:02:01794
795 int rv;
796
797 if (*total_bytes_written_ != kTestDataSize) {
798 // Recurse to finish writing all data.
799 int total_bytes_written = 0, total_bytes_read = 0;
800 std::string data_read;
[email protected]5eb431e22011-10-12 08:51:38801 TestWriteReadCompletionCallback callback(
[email protected]4c2048a2009-03-24 21:02:01802 stream_, &total_bytes_written, &total_bytes_read, &data_read);
[email protected]90499482013-06-01 00:39:50803 rv = stream_->Write(
804 drainable_.get(), drainable_->BytesRemaining(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07805 DCHECK_EQ(ERR_IO_PENDING, rv);
[email protected]4c2048a2009-03-24 21:02:01806 rv = callback.WaitForResult();
[email protected]9f49afb2012-02-16 09:59:20807 drainable_->DidConsume(total_bytes_written);
[email protected]4c2048a2009-03-24 21:02:01808 *total_bytes_written_ += total_bytes_written;
809 *total_bytes_read_ += total_bytes_read;
810 *data_read_ += data_read;
811 } else { // We're done writing all data. Start reading the data.
[email protected]cf02541b2012-04-11 08:02:17812 stream_->SeekSync(FROM_BEGIN, 0);
[email protected]4c2048a2009-03-24 21:02:01813
[email protected]5eb431e22011-10-12 08:51:38814 TestCompletionCallback callback;
[email protected]4c2048a2009-03-24 21:02:01815 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20816 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
[email protected]90499482013-06-01 00:39:50817 rv = stream_->Read(buf.get(), buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07818 if (rv == ERR_IO_PENDING) {
[email protected]2da659e2013-05-23 20:51:34819 base::MessageLoop::ScopedNestableTaskAllower allow(
820 base::MessageLoop::current());
[email protected]4c2048a2009-03-24 21:02:01821 rv = callback.WaitForResult();
[email protected]4c2048a2009-03-24 21:02:01822 }
823 EXPECT_LE(0, rv);
824 if (rv <= 0)
825 break;
826 *total_bytes_read_ += rv;
[email protected]9f49afb2012-02-16 09:59:20827 data_read_->append(buf->data(), rv);
[email protected]4c2048a2009-03-24 21:02:01828 }
829 }
830
831 result_ = *total_bytes_written_;
832 have_result_ = true;
833 if (waiting_for_result_)
[email protected]2da659e2013-05-23 20:51:34834 base::MessageLoop::current()->Quit();
[email protected]4c2048a2009-03-24 21:02:01835 }
836
837 int result_;
838 bool have_result_;
839 bool waiting_for_result_;
[email protected]8effd3f62011-03-25 16:29:07840 FileStream* stream_;
[email protected]4c2048a2009-03-24 21:02:01841 int* total_bytes_written_;
842 int* total_bytes_read_;
843 std::string* data_read_;
[email protected]5eb431e22011-10-12 08:51:38844 const CompletionCallback callback_;
[email protected]9f49afb2012-02-16 09:59:20845 scoped_refptr<IOBufferWithSize> test_data_;
846 scoped_refptr<DrainableIOBuffer> drainable_;
[email protected]4c2048a2009-03-24 21:02:01847
[email protected]5eb431e22011-10-12 08:51:38848 DISALLOW_COPY_AND_ASSIGN(TestWriteReadCompletionCallback);
[email protected]4c2048a2009-03-24 21:02:01849};
850
851TEST_F(FileStreamTest, AsyncWriteRead) {
852 int64 file_size;
853 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
854 EXPECT_TRUE(ok);
855
[email protected]aab1b9e2012-11-06 00:29:51856 scoped_ptr<FileStream> stream(new FileStream(NULL));
[email protected]4c2048a2009-03-24 21:02:01857 int flags = base::PLATFORM_FILE_OPEN |
858 base::PLATFORM_FILE_READ |
859 base::PLATFORM_FILE_WRITE |
860 base::PLATFORM_FILE_ASYNC;
[email protected]66af1d62013-03-06 23:13:20861 TestCompletionCallback open_callback;
862 int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
863 EXPECT_EQ(ERR_IO_PENDING, rv);
864 EXPECT_EQ(OK, open_callback.WaitForResult());
[email protected]4c2048a2009-03-24 21:02:01865
[email protected]aab1b9e2012-11-06 00:29:51866 int64 total_bytes_avail = stream->Available();
[email protected]4c2048a2009-03-24 21:02:01867 EXPECT_EQ(file_size, total_bytes_avail);
868
[email protected]aab1b9e2012-11-06 00:29:51869 int64 offset = stream->SeekSync(FROM_END, 0);
[email protected]4c2048a2009-03-24 21:02:01870 EXPECT_EQ(offset, file_size);
871
872 int total_bytes_written = 0;
873 int total_bytes_read = 0;
874 std::string data_read;
[email protected]aab1b9e2012-11-06 00:29:51875 TestWriteReadCompletionCallback callback(stream.get(), &total_bytes_written,
[email protected]4c2048a2009-03-24 21:02:01876 &total_bytes_read, &data_read);
877
[email protected]9f49afb2012-02-16 09:59:20878 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
[email protected]90499482013-06-01 00:39:50879 rv = stream->Write(buf.get(), buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07880 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01881 rv = callback.WaitForResult();
882 EXPECT_LT(0, rv);
883 EXPECT_EQ(kTestDataSize, total_bytes_written);
884
[email protected]aab1b9e2012-11-06 00:29:51885 stream.reset();
[email protected]4c2048a2009-03-24 21:02:01886
887 ok = file_util::GetFileSize(temp_file_path(), &file_size);
888 EXPECT_TRUE(ok);
889 EXPECT_EQ(kTestDataSize * 2, file_size);
890
891 EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
892 const std::string kExpectedFileData =
893 std::string(kTestData) + std::string(kTestData);
894 EXPECT_EQ(kExpectedFileData, data_read);
895}
896
[email protected]5eb431e22011-10-12 08:51:38897class TestWriteCloseCompletionCallback {
[email protected]4c2048a2009-03-24 21:02:01898 public:
[email protected]5eb431e22011-10-12 08:51:38899 TestWriteCloseCompletionCallback(FileStream* stream, int* total_bytes_written)
[email protected]4c2048a2009-03-24 21:02:01900 : result_(0),
901 have_result_(false),
902 waiting_for_result_(false),
903 stream_(stream),
[email protected]5eb431e22011-10-12 08:51:38904 total_bytes_written_(total_bytes_written),
905 callback_(base::Bind(&TestWriteCloseCompletionCallback::OnComplete,
[email protected]9f49afb2012-02-16 09:59:20906 base::Unretained(this))),
907 test_data_(CreateTestDataBuffer()),
[email protected]90499482013-06-01 00:39:50908 drainable_(new DrainableIOBuffer(test_data_.get(), kTestDataSize)) {}
[email protected]4c2048a2009-03-24 21:02:01909
910 int WaitForResult() {
911 DCHECK(!waiting_for_result_);
912 while (!have_result_) {
913 waiting_for_result_ = true;
[email protected]2da659e2013-05-23 20:51:34914 base::MessageLoop::current()->Run();
[email protected]4c2048a2009-03-24 21:02:01915 waiting_for_result_ = false;
916 }
917 have_result_ = false; // auto-reset for next callback
918 return result_;
919 }
920
[email protected]5eb431e22011-10-12 08:51:38921 const CompletionCallback& callback() const { return callback_; }
922
[email protected]4c2048a2009-03-24 21:02:01923 private:
[email protected]5eb431e22011-10-12 08:51:38924 void OnComplete(int result) {
925 DCHECK_LT(0, result);
926 *total_bytes_written_ += result;
[email protected]4c2048a2009-03-24 21:02:01927
928 int rv;
929
930 if (*total_bytes_written_ != kTestDataSize) {
931 // Recurse to finish writing all data.
932 int total_bytes_written = 0;
[email protected]5eb431e22011-10-12 08:51:38933 TestWriteCloseCompletionCallback callback(stream_, &total_bytes_written);
[email protected]90499482013-06-01 00:39:50934 rv = stream_->Write(
935 drainable_.get(), drainable_->BytesRemaining(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07936 DCHECK_EQ(ERR_IO_PENDING, rv);
[email protected]4c2048a2009-03-24 21:02:01937 rv = callback.WaitForResult();
[email protected]9f49afb2012-02-16 09:59:20938 drainable_->DidConsume(total_bytes_written);
[email protected]4c2048a2009-03-24 21:02:01939 *total_bytes_written_ += total_bytes_written;
[email protected]4c2048a2009-03-24 21:02:01940 }
941
942 result_ = *total_bytes_written_;
943 have_result_ = true;
944 if (waiting_for_result_)
[email protected]2da659e2013-05-23 20:51:34945 base::MessageLoop::current()->Quit();
[email protected]4c2048a2009-03-24 21:02:01946 }
947
948 int result_;
949 bool have_result_;
950 bool waiting_for_result_;
[email protected]8effd3f62011-03-25 16:29:07951 FileStream* stream_;
[email protected]4c2048a2009-03-24 21:02:01952 int* total_bytes_written_;
[email protected]5eb431e22011-10-12 08:51:38953 const CompletionCallback callback_;
[email protected]9f49afb2012-02-16 09:59:20954 scoped_refptr<IOBufferWithSize> test_data_;
955 scoped_refptr<DrainableIOBuffer> drainable_;
[email protected]4c2048a2009-03-24 21:02:01956
[email protected]5eb431e22011-10-12 08:51:38957 DISALLOW_COPY_AND_ASSIGN(TestWriteCloseCompletionCallback);
[email protected]4c2048a2009-03-24 21:02:01958};
959
960TEST_F(FileStreamTest, AsyncWriteClose) {
961 int64 file_size;
962 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
963 EXPECT_TRUE(ok);
964
[email protected]aab1b9e2012-11-06 00:29:51965 scoped_ptr<FileStream> stream(new FileStream(NULL));
[email protected]4c2048a2009-03-24 21:02:01966 int flags = base::PLATFORM_FILE_OPEN |
967 base::PLATFORM_FILE_READ |
968 base::PLATFORM_FILE_WRITE |
969 base::PLATFORM_FILE_ASYNC;
[email protected]66af1d62013-03-06 23:13:20970 TestCompletionCallback open_callback;
971 int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
972 EXPECT_EQ(ERR_IO_PENDING, rv);
973 EXPECT_EQ(OK, open_callback.WaitForResult());
[email protected]4c2048a2009-03-24 21:02:01974
[email protected]aab1b9e2012-11-06 00:29:51975 int64 total_bytes_avail = stream->Available();
[email protected]4c2048a2009-03-24 21:02:01976 EXPECT_EQ(file_size, total_bytes_avail);
977
[email protected]aab1b9e2012-11-06 00:29:51978 int64 offset = stream->SeekSync(FROM_END, 0);
[email protected]4c2048a2009-03-24 21:02:01979 EXPECT_EQ(offset, file_size);
980
981 int total_bytes_written = 0;
[email protected]aab1b9e2012-11-06 00:29:51982 TestWriteCloseCompletionCallback callback(stream.get(), &total_bytes_written);
[email protected]4c2048a2009-03-24 21:02:01983
[email protected]9f49afb2012-02-16 09:59:20984 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
[email protected]90499482013-06-01 00:39:50985 rv = stream->Write(buf.get(), buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07986 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01987 total_bytes_written = callback.WaitForResult();
988 EXPECT_LT(0, total_bytes_written);
989 EXPECT_EQ(kTestDataSize, total_bytes_written);
990
[email protected]aab1b9e2012-11-06 00:29:51991 stream.reset();
992
[email protected]4c2048a2009-03-24 21:02:01993 ok = file_util::GetFileSize(temp_file_path(), &file_size);
994 EXPECT_TRUE(ok);
995 EXPECT_EQ(kTestDataSize * 2, file_size);
996}
997
[email protected]0643a492009-03-09 15:49:20998// Tests truncating a file.
999TEST_F(FileStreamTest, Truncate) {
1000 int flags = base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE;
1001
[email protected]aab1b9e2012-11-06 00:29:511002 scoped_ptr<FileStream> write_stream(new FileStream(NULL));
1003 ASSERT_EQ(OK, write_stream->OpenSync(temp_file_path(), flags));
[email protected]0643a492009-03-09 15:49:201004
1005 // Write some data to the file.
1006 const char test_data[] = "0123456789";
[email protected]aab1b9e2012-11-06 00:29:511007 write_stream->WriteSync(test_data, arraysize(test_data));
[email protected]0643a492009-03-09 15:49:201008
1009 // Truncate the file.
[email protected]aab1b9e2012-11-06 00:29:511010 ASSERT_EQ(4, write_stream->Truncate(4));
[email protected]0643a492009-03-09 15:49:201011
1012 // Write again.
[email protected]aab1b9e2012-11-06 00:29:511013 write_stream->WriteSync(test_data, 4);
[email protected]0643a492009-03-09 15:49:201014
1015 // Close the stream.
[email protected]aab1b9e2012-11-06 00:29:511016 write_stream.reset();
[email protected]0643a492009-03-09 15:49:201017
1018 // Read in the contents and make sure we get back what we expected.
1019 std::string read_contents;
[email protected]82f84b92013-08-30 18:23:501020 EXPECT_TRUE(base::ReadFileToString(temp_file_path(), &read_contents));
[email protected]0643a492009-03-09 15:49:201021
[email protected]4c2048a2009-03-24 21:02:011022 EXPECT_EQ("01230123", read_contents);
[email protected]0643a492009-03-09 15:49:201023}
1024
[email protected]dbb747c2012-02-29 19:29:471025TEST_F(FileStreamTest, AsyncOpenAndDelete) {
1026 scoped_ptr<FileStream> stream(new FileStream(NULL));
1027 int flags = base::PLATFORM_FILE_OPEN |
1028 base::PLATFORM_FILE_WRITE |
1029 base::PLATFORM_FILE_ASYNC;
1030 TestCompletionCallback open_callback;
1031 int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
1032 EXPECT_EQ(ERR_IO_PENDING, rv);
1033
1034 // Delete the stream without waiting for the open operation to be
1035 // complete. Should be safe.
1036 stream.reset();
1037 // open_callback won't be called.
[email protected]2da659e2013-05-23 20:51:341038 base::MessageLoop::current()->RunUntilIdle();
[email protected]dbb747c2012-02-29 19:29:471039 EXPECT_FALSE(open_callback.have_result());
1040}
1041
[email protected]bfb88ec2013-02-27 20:21:351042// Verify that async Write() errors are mapped correctly.
1043TEST_F(FileStreamTest, AsyncWriteError) {
1044 scoped_ptr<FileStream> stream(new FileStream(NULL));
1045 int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
1046 base::PLATFORM_FILE_WRITE |
1047 base::PLATFORM_FILE_ASYNC;
[email protected]bfb88ec2013-02-27 20:21:351048 TestCompletionCallback callback;
[email protected]66af1d62013-03-06 23:13:201049 int rv = stream->Open(temp_file_path(), flags, callback.callback());
1050 EXPECT_EQ(ERR_IO_PENDING, rv);
1051 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]bfb88ec2013-02-27 20:21:351052
1053 // Try passing NULL buffer to Write() and check that it fails.
1054 scoped_refptr<IOBuffer> buf = new WrappedIOBuffer(NULL);
[email protected]90499482013-06-01 00:39:501055 rv = stream->Write(buf.get(), 1, callback.callback());
[email protected]bfb88ec2013-02-27 20:21:351056 if (rv == ERR_IO_PENDING)
1057 rv = callback.WaitForResult();
1058 EXPECT_LT(rv, 0);
1059}
1060
1061// Verify that async Read() errors are mapped correctly.
1062TEST_F(FileStreamTest, AsyncReadError) {
1063 scoped_ptr<FileStream> stream(new FileStream(NULL));
1064 int flags = base::PLATFORM_FILE_OPEN |
1065 base::PLATFORM_FILE_READ |
1066 base::PLATFORM_FILE_ASYNC;
[email protected]bfb88ec2013-02-27 20:21:351067 TestCompletionCallback callback;
[email protected]66af1d62013-03-06 23:13:201068 int rv = stream->Open(temp_file_path(), flags, callback.callback());
1069 EXPECT_EQ(ERR_IO_PENDING, rv);
1070 EXPECT_EQ(OK, callback.WaitForResult());
[email protected]bfb88ec2013-02-27 20:21:351071
1072 // Try passing NULL buffer to Read() and check that it fails.
1073 scoped_refptr<IOBuffer> buf = new WrappedIOBuffer(NULL);
[email protected]90499482013-06-01 00:39:501074 rv = stream->Read(buf.get(), 1, callback.callback());
[email protected]bfb88ec2013-02-27 20:21:351075 if (rv == ERR_IO_PENDING)
1076 rv = callback.WaitForResult();
1077 EXPECT_LT(rv, 0);
1078}
1079
[email protected]4c2048a2009-03-24 21:02:011080} // namespace
[email protected]96d73822011-10-10 02:11:241081
[email protected]8effd3f62011-03-25 16:29:071082} // namespace net