blob: f9882c885cdd80088ec410d3621acd8126344563 [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]ad74a592011-01-21 18:40:5510#include "base/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() {
47 file_util::Delete(temp_file_path_, false);
48
49 PlatformTest::TearDown();
50 }
[email protected]96d73822011-10-10 02:11:2451
[email protected]07167e8f2009-01-26 21:38:1152 const 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]07167e8f2009-01-26 21:38:1155 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));
94 EXPECT_FALSE(base::ClosePlatformFile(file));
[email protected]21da6eb2008-11-03 17:18:1495}
96
[email protected]92aad5222009-02-09 22:26:4197// Test the use of FileStream with a file handle provided at construction.
98TEST_F(FileStreamTest, UseFileHandle) {
99 bool created = false;
100
101 // 1. Test reading with a file handle.
102 ASSERT_EQ(kTestDataSize,
103 file_util::WriteFile(temp_file_path(), kTestData, kTestDataSize));
104 int flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_READ;
105 base::PlatformFile file = base::CreatePlatformFile(
[email protected]ed65fec2010-08-31 19:30:27106 temp_file_path(), flags, &created, NULL);
[email protected]92aad5222009-02-09 22:26:41107
108 // Seek to the beginning of the file and read.
[email protected]aab1b9e2012-11-06 00:29:51109 scoped_ptr<FileStream> read_stream(new FileStream(file, flags, NULL));
110 ASSERT_EQ(0, read_stream->SeekSync(FROM_BEGIN, 0));
111 ASSERT_EQ(kTestDataSize, read_stream->Available());
[email protected]92aad5222009-02-09 22:26:41112 // Read into buffer and compare.
113 char buffer[kTestDataSize];
[email protected]5eb431e22011-10-12 08:51:38114 ASSERT_EQ(kTestDataSize,
[email protected]aab1b9e2012-11-06 00:29:51115 read_stream->ReadSync(buffer, kTestDataSize));
[email protected]92aad5222009-02-09 22:26:41116 ASSERT_EQ(0, memcmp(kTestData, buffer, kTestDataSize));
[email protected]aab1b9e2012-11-06 00:29:51117 read_stream.reset();
[email protected]92aad5222009-02-09 22:26:41118
119 // 2. Test writing with a file handle.
120 file_util::Delete(temp_file_path(), false);
121 flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_WRITE;
[email protected]ed65fec2010-08-31 19:30:27122 file = base::CreatePlatformFile(temp_file_path(), flags, &created, NULL);
[email protected]92aad5222009-02-09 22:26:41123
[email protected]aab1b9e2012-11-06 00:29:51124 scoped_ptr<FileStream> write_stream(new FileStream(file, flags, NULL));
125 ASSERT_EQ(0, write_stream->SeekSync(FROM_BEGIN, 0));
[email protected]5eb431e22011-10-12 08:51:38126 ASSERT_EQ(kTestDataSize,
[email protected]aab1b9e2012-11-06 00:29:51127 write_stream->WriteSync(kTestData, kTestDataSize));
128 write_stream.reset();
[email protected]92aad5222009-02-09 22:26:41129
130 // Read into buffer and compare to make sure the handle worked fine.
131 ASSERT_EQ(kTestDataSize,
132 file_util::ReadFile(temp_file_path(), buffer, kTestDataSize));
133 ASSERT_EQ(0, memcmp(kTestData, buffer, kTestDataSize));
134}
135
[email protected]21da6eb2008-11-03 17:18:14136TEST_F(FileStreamTest, UseClosedStream) {
[email protected]10342992012-02-02 18:49:43137 FileStream stream(NULL);
[email protected]21da6eb2008-11-03 17:18:14138
139 EXPECT_FALSE(stream.IsOpen());
140
141 // Try seeking...
[email protected]cf02541b2012-04-11 08:02:17142 int64 new_offset = stream.SeekSync(FROM_BEGIN, 5);
[email protected]8effd3f62011-03-25 16:29:07143 EXPECT_EQ(ERR_UNEXPECTED, new_offset);
[email protected]21da6eb2008-11-03 17:18:14144
145 // Try available...
146 int64 avail = stream.Available();
[email protected]8effd3f62011-03-25 16:29:07147 EXPECT_EQ(ERR_UNEXPECTED, avail);
[email protected]21da6eb2008-11-03 17:18:14148
149 // Try reading...
150 char buf[10];
[email protected]6b230f42012-02-15 04:08:41151 int rv = stream.ReadSync(buf, arraysize(buf));
[email protected]8effd3f62011-03-25 16:29:07152 EXPECT_EQ(ERR_UNEXPECTED, rv);
[email protected]21da6eb2008-11-03 17:18:14153}
154
155TEST_F(FileStreamTest, BasicRead) {
156 int64 file_size;
157 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
158 EXPECT_TRUE(ok);
159
[email protected]10342992012-02-02 18:49:43160 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38161 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14162 base::PLATFORM_FILE_READ;
[email protected]fe57eb22012-02-09 05:59:40163 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07164 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14165
166 int64 total_bytes_avail = stream.Available();
167 EXPECT_EQ(file_size, total_bytes_avail);
168
[email protected]4c2048a2009-03-24 21:02:01169 int total_bytes_read = 0;
[email protected]21da6eb2008-11-03 17:18:14170
171 std::string data_read;
172 for (;;) {
173 char buf[4];
[email protected]6b230f42012-02-15 04:08:41174 rv = stream.ReadSync(buf, arraysize(buf));
[email protected]21da6eb2008-11-03 17:18:14175 EXPECT_LE(0, rv);
176 if (rv <= 0)
177 break;
178 total_bytes_read += rv;
179 data_read.append(buf, rv);
180 }
181 EXPECT_EQ(file_size, total_bytes_read);
[email protected]4c2048a2009-03-24 21:02:01182 EXPECT_EQ(kTestData, data_read);
[email protected]21da6eb2008-11-03 17:18:14183}
184
185TEST_F(FileStreamTest, AsyncRead) {
186 int64 file_size;
187 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
188 EXPECT_TRUE(ok);
189
[email protected]10342992012-02-02 18:49:43190 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38191 int flags = base::PLATFORM_FILE_OPEN |
192 base::PLATFORM_FILE_READ |
[email protected]21da6eb2008-11-03 17:18:14193 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:40194 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07195 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14196
197 int64 total_bytes_avail = stream.Available();
198 EXPECT_EQ(file_size, total_bytes_avail);
199
[email protected]5eb431e22011-10-12 08:51:38200 TestCompletionCallback callback;
[email protected]21da6eb2008-11-03 17:18:14201
[email protected]4c2048a2009-03-24 21:02:01202 int total_bytes_read = 0;
[email protected]21da6eb2008-11-03 17:18:14203
204 std::string data_read;
205 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20206 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
207 rv = stream.Read(buf, buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07208 if (rv == ERR_IO_PENDING)
[email protected]21da6eb2008-11-03 17:18:14209 rv = callback.WaitForResult();
210 EXPECT_LE(0, rv);
211 if (rv <= 0)
212 break;
213 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20214 data_read.append(buf->data(), rv);
[email protected]21da6eb2008-11-03 17:18:14215 }
216 EXPECT_EQ(file_size, total_bytes_read);
[email protected]4c2048a2009-03-24 21:02:01217 EXPECT_EQ(kTestData, data_read);
218}
219
[email protected]06b802b2012-02-22 03:34:54220TEST_F(FileStreamTest, AsyncRead_EarlyDelete) {
221 int64 file_size;
222 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
223 EXPECT_TRUE(ok);
224
225 scoped_ptr<FileStream> stream(new FileStream(NULL));
226 int flags = base::PLATFORM_FILE_OPEN |
227 base::PLATFORM_FILE_READ |
228 base::PLATFORM_FILE_ASYNC;
229 TestCompletionCallback callback;
230 int rv = stream->Open(temp_file_path(), flags, callback.callback());
231 EXPECT_EQ(ERR_IO_PENDING, rv);
232 EXPECT_EQ(OK, callback.WaitForResult());
233
234 int64 total_bytes_avail = stream->Available();
235 EXPECT_EQ(file_size, total_bytes_avail);
236
237 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
238 rv = stream->Read(buf, buf->size(), callback.callback());
239 stream.reset(); // Delete instead of closing it.
240 if (rv < 0) {
241 EXPECT_EQ(ERR_IO_PENDING, rv);
242 // The callback should not be called if the request is cancelled.
243 MessageLoop::current()->RunAllPending();
244 EXPECT_FALSE(callback.have_result());
245 } else {
246 EXPECT_EQ(std::string(kTestData, rv), std::string(buf->data(), rv));
247 }
248}
249
[email protected]21da6eb2008-11-03 17:18:14250TEST_F(FileStreamTest, BasicRead_FromOffset) {
251 int64 file_size;
252 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
253 EXPECT_TRUE(ok);
254
[email protected]10342992012-02-02 18:49:43255 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38256 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14257 base::PLATFORM_FILE_READ;
[email protected]fe57eb22012-02-09 05:59:40258 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07259 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14260
261 const int64 kOffset = 3;
[email protected]cf02541b2012-04-11 08:02:17262 int64 new_offset = stream.SeekSync(FROM_BEGIN, kOffset);
[email protected]21da6eb2008-11-03 17:18:14263 EXPECT_EQ(kOffset, new_offset);
264
265 int64 total_bytes_avail = stream.Available();
266 EXPECT_EQ(file_size - kOffset, total_bytes_avail);
267
268 int64 total_bytes_read = 0;
269
270 std::string data_read;
271 for (;;) {
272 char buf[4];
[email protected]6b230f42012-02-15 04:08:41273 rv = stream.ReadSync(buf, arraysize(buf));
[email protected]21da6eb2008-11-03 17:18:14274 EXPECT_LE(0, rv);
275 if (rv <= 0)
276 break;
277 total_bytes_read += rv;
278 data_read.append(buf, rv);
279 }
280 EXPECT_EQ(file_size - kOffset, total_bytes_read);
281 EXPECT_TRUE(data_read == kTestData + kOffset);
[email protected]4c2048a2009-03-24 21:02:01282 EXPECT_EQ(kTestData + kOffset, data_read);
[email protected]21da6eb2008-11-03 17:18:14283}
284
285TEST_F(FileStreamTest, AsyncRead_FromOffset) {
286 int64 file_size;
287 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
288 EXPECT_TRUE(ok);
289
[email protected]10342992012-02-02 18:49:43290 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38291 int flags = base::PLATFORM_FILE_OPEN |
292 base::PLATFORM_FILE_READ |
[email protected]21da6eb2008-11-03 17:18:14293 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:40294 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07295 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14296
[email protected]cf02541b2012-04-11 08:02:17297 TestInt64CompletionCallback callback64;
[email protected]21da6eb2008-11-03 17:18:14298 const int64 kOffset = 3;
[email protected]cf02541b2012-04-11 08:02:17299 rv = stream.Seek(FROM_BEGIN, kOffset, callback64.callback());
300 ASSERT_EQ(ERR_IO_PENDING, rv);
301 int64 new_offset = callback64.WaitForResult();
[email protected]21da6eb2008-11-03 17:18:14302 EXPECT_EQ(kOffset, new_offset);
303
304 int64 total_bytes_avail = stream.Available();
305 EXPECT_EQ(file_size - kOffset, total_bytes_avail);
306
[email protected]5eb431e22011-10-12 08:51:38307 TestCompletionCallback callback;
[email protected]21da6eb2008-11-03 17:18:14308
[email protected]4c2048a2009-03-24 21:02:01309 int total_bytes_read = 0;
[email protected]21da6eb2008-11-03 17:18:14310
311 std::string data_read;
312 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20313 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
314 rv = stream.Read(buf, buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07315 if (rv == ERR_IO_PENDING)
[email protected]21da6eb2008-11-03 17:18:14316 rv = callback.WaitForResult();
317 EXPECT_LE(0, rv);
318 if (rv <= 0)
319 break;
320 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20321 data_read.append(buf->data(), rv);
[email protected]21da6eb2008-11-03 17:18:14322 }
323 EXPECT_EQ(file_size - kOffset, total_bytes_read);
[email protected]4c2048a2009-03-24 21:02:01324 EXPECT_EQ(kTestData + kOffset, data_read);
[email protected]21da6eb2008-11-03 17:18:14325}
326
327TEST_F(FileStreamTest, SeekAround) {
[email protected]10342992012-02-02 18:49:43328 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38329 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14330 base::PLATFORM_FILE_READ;
[email protected]fe57eb22012-02-09 05:59:40331 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07332 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14333
334 const int64 kOffset = 3;
[email protected]cf02541b2012-04-11 08:02:17335 int64 new_offset = stream.SeekSync(FROM_BEGIN, kOffset);
[email protected]21da6eb2008-11-03 17:18:14336 EXPECT_EQ(kOffset, new_offset);
337
[email protected]cf02541b2012-04-11 08:02:17338 new_offset = stream.SeekSync(FROM_CURRENT, kOffset);
[email protected]21da6eb2008-11-03 17:18:14339 EXPECT_EQ(2 * kOffset, new_offset);
340
[email protected]cf02541b2012-04-11 08:02:17341 new_offset = stream.SeekSync(FROM_CURRENT, -kOffset);
[email protected]21da6eb2008-11-03 17:18:14342 EXPECT_EQ(kOffset, new_offset);
343
344 const int kTestDataLen = arraysize(kTestData) - 1;
345
[email protected]cf02541b2012-04-11 08:02:17346 new_offset = stream.SeekSync(FROM_END, -kTestDataLen);
347 EXPECT_EQ(0, new_offset);
348}
349
350TEST_F(FileStreamTest, AsyncSeekAround) {
351 FileStream stream(NULL);
352 int flags = base::PLATFORM_FILE_OPEN |
353 base::PLATFORM_FILE_ASYNC |
354 base::PLATFORM_FILE_READ;
355 int rv = stream.OpenSync(temp_file_path(), flags);
356 EXPECT_EQ(OK, rv);
357
358 TestInt64CompletionCallback callback;
359
360 const int64 kOffset = 3;
361 rv = stream.Seek(FROM_BEGIN, kOffset, callback.callback());
362 ASSERT_EQ(ERR_IO_PENDING, rv);
363 int64 new_offset = callback.WaitForResult();
364 EXPECT_EQ(kOffset, new_offset);
365
366 rv = stream.Seek(FROM_CURRENT, kOffset, callback.callback());
367 ASSERT_EQ(ERR_IO_PENDING, rv);
368 new_offset = callback.WaitForResult();
369 EXPECT_EQ(2 * kOffset, new_offset);
370
371 rv = stream.Seek(FROM_CURRENT, -kOffset, callback.callback());
372 ASSERT_EQ(ERR_IO_PENDING, rv);
373 new_offset = callback.WaitForResult();
374 EXPECT_EQ(kOffset, new_offset);
375
376 const int kTestDataLen = arraysize(kTestData) - 1;
377
378 rv = stream.Seek(FROM_END, -kTestDataLen, callback.callback());
379 ASSERT_EQ(ERR_IO_PENDING, rv);
380 new_offset = callback.WaitForResult();
[email protected]21da6eb2008-11-03 17:18:14381 EXPECT_EQ(0, new_offset);
382}
383
384TEST_F(FileStreamTest, BasicWrite) {
[email protected]aab1b9e2012-11-06 00:29:51385 scoped_ptr<FileStream> stream(new FileStream(NULL));
[email protected]f0a51fb52009-03-05 12:46:38386 int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
[email protected]21da6eb2008-11-03 17:18:14387 base::PLATFORM_FILE_WRITE;
[email protected]aab1b9e2012-11-06 00:29:51388 int rv = stream->OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07389 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14390
391 int64 file_size;
392 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
393 EXPECT_TRUE(ok);
394 EXPECT_EQ(0, file_size);
395
[email protected]aab1b9e2012-11-06 00:29:51396 rv = stream->WriteSync(kTestData, kTestDataSize);
[email protected]21da6eb2008-11-03 17:18:14397 EXPECT_EQ(kTestDataSize, rv);
[email protected]aab1b9e2012-11-06 00:29:51398 stream.reset();
[email protected]21da6eb2008-11-03 17:18:14399
400 ok = file_util::GetFileSize(temp_file_path(), &file_size);
401 EXPECT_TRUE(ok);
402 EXPECT_EQ(kTestDataSize, file_size);
403}
404
405TEST_F(FileStreamTest, AsyncWrite) {
[email protected]10342992012-02-02 18:49:43406 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38407 int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
408 base::PLATFORM_FILE_WRITE |
[email protected]21da6eb2008-11-03 17:18:14409 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:40410 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07411 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14412
413 int64 file_size;
414 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
415 EXPECT_TRUE(ok);
416 EXPECT_EQ(0, file_size);
417
[email protected]5eb431e22011-10-12 08:51:38418 TestCompletionCallback callback;
[email protected]4c2048a2009-03-24 21:02:01419 int total_bytes_written = 0;
[email protected]21da6eb2008-11-03 17:18:14420
[email protected]9f49afb2012-02-16 09:59:20421 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
422 scoped_refptr<DrainableIOBuffer> drainable =
423 new DrainableIOBuffer(buf, buf->size());
[email protected]21da6eb2008-11-03 17:18:14424 while (total_bytes_written != kTestDataSize) {
[email protected]9f49afb2012-02-16 09:59:20425 rv = stream.Write(drainable, drainable->BytesRemaining(),
[email protected]5eb431e22011-10-12 08:51:38426 callback.callback());
[email protected]8effd3f62011-03-25 16:29:07427 if (rv == ERR_IO_PENDING)
[email protected]21da6eb2008-11-03 17:18:14428 rv = callback.WaitForResult();
429 EXPECT_LT(0, rv);
430 if (rv <= 0)
431 break;
[email protected]9f49afb2012-02-16 09:59:20432 drainable->DidConsume(rv);
[email protected]21da6eb2008-11-03 17:18:14433 total_bytes_written += rv;
434 }
435 ok = file_util::GetFileSize(temp_file_path(), &file_size);
436 EXPECT_TRUE(ok);
437 EXPECT_EQ(file_size, total_bytes_written);
438}
439
[email protected]aab1b9e2012-11-06 00:29:51440TEST_F(FileStreamTest, AsyncWrite_EarlyDelete) {
441 scoped_ptr<FileStream> stream(new FileStream(NULL));
[email protected]4c2048a2009-03-24 21:02:01442 int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
443 base::PLATFORM_FILE_WRITE |
444 base::PLATFORM_FILE_ASYNC;
[email protected]aab1b9e2012-11-06 00:29:51445 int rv = stream->OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07446 EXPECT_EQ(OK, rv);
[email protected]4c2048a2009-03-24 21:02:01447
448 int64 file_size;
449 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
450 EXPECT_TRUE(ok);
451 EXPECT_EQ(0, file_size);
452
[email protected]5eb431e22011-10-12 08:51:38453 TestCompletionCallback callback;
[email protected]4c2048a2009-03-24 21:02:01454
[email protected]9f49afb2012-02-16 09:59:20455 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
[email protected]aab1b9e2012-11-06 00:29:51456 rv = stream->Write(buf, buf->size(), callback.callback());
457 stream.reset();
[email protected]3828a752009-06-03 23:05:59458 if (rv < 0) {
[email protected]8effd3f62011-03-25 16:29:07459 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3828a752009-06-03 23:05:59460 // The callback should not be called if the request is cancelled.
461 MessageLoop::current()->RunAllPending();
462 EXPECT_FALSE(callback.have_result());
463 } else {
464 ok = file_util::GetFileSize(temp_file_path(), &file_size);
465 EXPECT_TRUE(ok);
466 EXPECT_EQ(file_size, rv);
467 }
[email protected]4c2048a2009-03-24 21:02:01468}
469
[email protected]21da6eb2008-11-03 17:18:14470TEST_F(FileStreamTest, BasicWrite_FromOffset) {
[email protected]aab1b9e2012-11-06 00:29:51471 scoped_ptr<FileStream> stream(new FileStream(NULL));
[email protected]f0a51fb52009-03-05 12:46:38472 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14473 base::PLATFORM_FILE_WRITE;
[email protected]aab1b9e2012-11-06 00:29:51474 int rv = stream->OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07475 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14476
477 int64 file_size;
478 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
479 EXPECT_TRUE(ok);
480 EXPECT_EQ(kTestDataSize, file_size);
481
482 const int64 kOffset = 0;
[email protected]aab1b9e2012-11-06 00:29:51483 int64 new_offset = stream->SeekSync(FROM_END, kOffset);
[email protected]21da6eb2008-11-03 17:18:14484 EXPECT_EQ(kTestDataSize, new_offset);
485
[email protected]aab1b9e2012-11-06 00:29:51486 rv = stream->WriteSync(kTestData, kTestDataSize);
[email protected]21da6eb2008-11-03 17:18:14487 EXPECT_EQ(kTestDataSize, rv);
[email protected]aab1b9e2012-11-06 00:29:51488 stream.reset();
[email protected]21da6eb2008-11-03 17:18:14489
490 ok = file_util::GetFileSize(temp_file_path(), &file_size);
491 EXPECT_TRUE(ok);
492 EXPECT_EQ(kTestDataSize * 2, file_size);
493}
494
495TEST_F(FileStreamTest, AsyncWrite_FromOffset) {
496 int64 file_size;
497 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
498 EXPECT_TRUE(ok);
499
[email protected]10342992012-02-02 18:49:43500 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38501 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14502 base::PLATFORM_FILE_WRITE |
503 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:40504 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07505 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14506
[email protected]cf02541b2012-04-11 08:02:17507 TestInt64CompletionCallback callback64;
[email protected]21da6eb2008-11-03 17:18:14508 const int64 kOffset = 0;
[email protected]cf02541b2012-04-11 08:02:17509 rv = stream.Seek(FROM_END, kOffset, callback64.callback());
510 ASSERT_EQ(ERR_IO_PENDING, rv);
511 int64 new_offset = callback64.WaitForResult();
[email protected]21da6eb2008-11-03 17:18:14512 EXPECT_EQ(kTestDataSize, new_offset);
513
[email protected]5eb431e22011-10-12 08:51:38514 TestCompletionCallback callback;
[email protected]4c2048a2009-03-24 21:02:01515 int total_bytes_written = 0;
[email protected]21da6eb2008-11-03 17:18:14516
[email protected]9f49afb2012-02-16 09:59:20517 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
518 scoped_refptr<DrainableIOBuffer> drainable =
519 new DrainableIOBuffer(buf, buf->size());
[email protected]21da6eb2008-11-03 17:18:14520 while (total_bytes_written != kTestDataSize) {
[email protected]9f49afb2012-02-16 09:59:20521 rv = stream.Write(drainable, drainable->BytesRemaining(),
[email protected]5eb431e22011-10-12 08:51:38522 callback.callback());
[email protected]8effd3f62011-03-25 16:29:07523 if (rv == ERR_IO_PENDING)
[email protected]21da6eb2008-11-03 17:18:14524 rv = callback.WaitForResult();
525 EXPECT_LT(0, rv);
526 if (rv <= 0)
527 break;
[email protected]9f49afb2012-02-16 09:59:20528 drainable->DidConsume(rv);
[email protected]21da6eb2008-11-03 17:18:14529 total_bytes_written += rv;
530 }
531 ok = file_util::GetFileSize(temp_file_path(), &file_size);
532 EXPECT_TRUE(ok);
533 EXPECT_EQ(file_size, kTestDataSize * 2);
534}
535
536TEST_F(FileStreamTest, BasicReadWrite) {
537 int64 file_size;
538 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
539 EXPECT_TRUE(ok);
540
[email protected]aab1b9e2012-11-06 00:29:51541 scoped_ptr<FileStream> stream(new FileStream(NULL));
[email protected]f0a51fb52009-03-05 12:46:38542 int flags = base::PLATFORM_FILE_OPEN |
543 base::PLATFORM_FILE_READ |
[email protected]21da6eb2008-11-03 17:18:14544 base::PLATFORM_FILE_WRITE;
[email protected]aab1b9e2012-11-06 00:29:51545 int rv = stream->OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07546 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14547
[email protected]aab1b9e2012-11-06 00:29:51548 int64 total_bytes_avail = stream->Available();
[email protected]21da6eb2008-11-03 17:18:14549 EXPECT_EQ(file_size, total_bytes_avail);
550
[email protected]4c2048a2009-03-24 21:02:01551 int total_bytes_read = 0;
[email protected]21da6eb2008-11-03 17:18:14552
553 std::string data_read;
554 for (;;) {
555 char buf[4];
[email protected]aab1b9e2012-11-06 00:29:51556 rv = stream->ReadSync(buf, arraysize(buf));
[email protected]21da6eb2008-11-03 17:18:14557 EXPECT_LE(0, rv);
558 if (rv <= 0)
559 break;
560 total_bytes_read += rv;
561 data_read.append(buf, rv);
562 }
563 EXPECT_EQ(file_size, total_bytes_read);
564 EXPECT_TRUE(data_read == kTestData);
565
[email protected]aab1b9e2012-11-06 00:29:51566 rv = stream->WriteSync(kTestData, kTestDataSize);
[email protected]21da6eb2008-11-03 17:18:14567 EXPECT_EQ(kTestDataSize, rv);
[email protected]aab1b9e2012-11-06 00:29:51568 stream.reset();
[email protected]21da6eb2008-11-03 17:18:14569
570 ok = file_util::GetFileSize(temp_file_path(), &file_size);
571 EXPECT_TRUE(ok);
572 EXPECT_EQ(kTestDataSize * 2, file_size);
573}
574
[email protected]4c2048a2009-03-24 21:02:01575TEST_F(FileStreamTest, BasicWriteRead) {
576 int64 file_size;
577 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
578 EXPECT_TRUE(ok);
579
[email protected]aab1b9e2012-11-06 00:29:51580 scoped_ptr<FileStream> stream(new FileStream(NULL));
[email protected]4c2048a2009-03-24 21:02:01581 int flags = base::PLATFORM_FILE_OPEN |
582 base::PLATFORM_FILE_READ |
583 base::PLATFORM_FILE_WRITE;
[email protected]aab1b9e2012-11-06 00:29:51584 int rv = stream->OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07585 EXPECT_EQ(OK, rv);
[email protected]4c2048a2009-03-24 21:02:01586
[email protected]aab1b9e2012-11-06 00:29:51587 int64 total_bytes_avail = stream->Available();
[email protected]4c2048a2009-03-24 21:02:01588 EXPECT_EQ(file_size, total_bytes_avail);
589
[email protected]aab1b9e2012-11-06 00:29:51590 int64 offset = stream->SeekSync(FROM_END, 0);
[email protected]4c2048a2009-03-24 21:02:01591 EXPECT_EQ(offset, file_size);
592
[email protected]aab1b9e2012-11-06 00:29:51593 rv = stream->WriteSync(kTestData, kTestDataSize);
[email protected]4c2048a2009-03-24 21:02:01594 EXPECT_EQ(kTestDataSize, rv);
595
[email protected]aab1b9e2012-11-06 00:29:51596 offset = stream->SeekSync(FROM_BEGIN, 0);
[email protected]4c2048a2009-03-24 21:02:01597 EXPECT_EQ(0, offset);
598
599 int64 total_bytes_read = 0;
600
601 std::string data_read;
602 for (;;) {
603 char buf[4];
[email protected]aab1b9e2012-11-06 00:29:51604 rv = stream->ReadSync(buf, arraysize(buf));
[email protected]4c2048a2009-03-24 21:02:01605 EXPECT_LE(0, rv);
606 if (rv <= 0)
607 break;
608 total_bytes_read += rv;
609 data_read.append(buf, rv);
610 }
[email protected]aab1b9e2012-11-06 00:29:51611 stream.reset();
[email protected]4c2048a2009-03-24 21:02:01612
613 ok = file_util::GetFileSize(temp_file_path(), &file_size);
614 EXPECT_TRUE(ok);
615 EXPECT_EQ(kTestDataSize * 2, file_size);
616 EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
617
618 const std::string kExpectedFileData =
619 std::string(kTestData) + std::string(kTestData);
620 EXPECT_EQ(kExpectedFileData, data_read);
621}
622
623TEST_F(FileStreamTest, BasicAsyncReadWrite) {
624 int64 file_size;
625 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
626 EXPECT_TRUE(ok);
627
[email protected]aab1b9e2012-11-06 00:29:51628 scoped_ptr<FileStream> stream(new FileStream(NULL));
[email protected]4c2048a2009-03-24 21:02:01629 int flags = base::PLATFORM_FILE_OPEN |
630 base::PLATFORM_FILE_READ |
631 base::PLATFORM_FILE_WRITE |
632 base::PLATFORM_FILE_ASYNC;
[email protected]aab1b9e2012-11-06 00:29:51633 int rv = stream->OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07634 EXPECT_EQ(OK, rv);
[email protected]4c2048a2009-03-24 21:02:01635
[email protected]aab1b9e2012-11-06 00:29:51636 int64 total_bytes_avail = stream->Available();
[email protected]4c2048a2009-03-24 21:02:01637 EXPECT_EQ(file_size, total_bytes_avail);
638
[email protected]5eb431e22011-10-12 08:51:38639 TestCompletionCallback callback;
[email protected]4c2048a2009-03-24 21:02:01640 int64 total_bytes_read = 0;
641
642 std::string data_read;
643 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20644 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
[email protected]aab1b9e2012-11-06 00:29:51645 rv = stream->Read(buf, buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07646 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01647 rv = callback.WaitForResult();
648 EXPECT_LE(0, rv);
649 if (rv <= 0)
650 break;
651 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20652 data_read.append(buf->data(), rv);
[email protected]4c2048a2009-03-24 21:02:01653 }
654 EXPECT_EQ(file_size, total_bytes_read);
655 EXPECT_TRUE(data_read == kTestData);
656
657 int total_bytes_written = 0;
658
[email protected]9f49afb2012-02-16 09:59:20659 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
660 scoped_refptr<DrainableIOBuffer> drainable =
661 new DrainableIOBuffer(buf, buf->size());
[email protected]4c2048a2009-03-24 21:02:01662 while (total_bytes_written != kTestDataSize) {
[email protected]aab1b9e2012-11-06 00:29:51663 rv = stream->Write(drainable, drainable->BytesRemaining(),
664 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_LT(0, rv);
668 if (rv <= 0)
669 break;
[email protected]9f49afb2012-02-16 09:59:20670 drainable->DidConsume(rv);
[email protected]4c2048a2009-03-24 21:02:01671 total_bytes_written += rv;
672 }
673
[email protected]aab1b9e2012-11-06 00:29:51674 stream.reset();
[email protected]4c2048a2009-03-24 21:02:01675
676 ok = file_util::GetFileSize(temp_file_path(), &file_size);
677 EXPECT_TRUE(ok);
678 EXPECT_EQ(kTestDataSize * 2, file_size);
679}
680
681TEST_F(FileStreamTest, BasicAsyncWriteRead) {
682 int64 file_size;
683 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
684 EXPECT_TRUE(ok);
685
[email protected]aab1b9e2012-11-06 00:29:51686 scoped_ptr<FileStream> stream(new FileStream(NULL));
[email protected]4c2048a2009-03-24 21:02:01687 int flags = base::PLATFORM_FILE_OPEN |
688 base::PLATFORM_FILE_READ |
689 base::PLATFORM_FILE_WRITE |
690 base::PLATFORM_FILE_ASYNC;
[email protected]aab1b9e2012-11-06 00:29:51691 int rv = stream->OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07692 EXPECT_EQ(OK, rv);
[email protected]4c2048a2009-03-24 21:02:01693
[email protected]aab1b9e2012-11-06 00:29:51694 int64 total_bytes_avail = stream->Available();
[email protected]4c2048a2009-03-24 21:02:01695 EXPECT_EQ(file_size, total_bytes_avail);
696
[email protected]cf02541b2012-04-11 08:02:17697 TestInt64CompletionCallback callback64;
[email protected]aab1b9e2012-11-06 00:29:51698 rv = stream->Seek(FROM_END, 0, callback64.callback());
[email protected]cf02541b2012-04-11 08:02:17699 ASSERT_EQ(ERR_IO_PENDING, rv);
700 int64 offset = callback64.WaitForResult();
[email protected]4c2048a2009-03-24 21:02:01701 EXPECT_EQ(offset, file_size);
702
[email protected]5eb431e22011-10-12 08:51:38703 TestCompletionCallback callback;
[email protected]4c2048a2009-03-24 21:02:01704 int total_bytes_written = 0;
705
[email protected]9f49afb2012-02-16 09:59:20706 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
707 scoped_refptr<DrainableIOBuffer> drainable =
708 new DrainableIOBuffer(buf, buf->size());
[email protected]4c2048a2009-03-24 21:02:01709 while (total_bytes_written != kTestDataSize) {
[email protected]aab1b9e2012-11-06 00:29:51710 rv = stream->Write(drainable, drainable->BytesRemaining(),
[email protected]5eb431e22011-10-12 08:51:38711 callback.callback());
[email protected]8effd3f62011-03-25 16:29:07712 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01713 rv = callback.WaitForResult();
714 EXPECT_LT(0, rv);
715 if (rv <= 0)
716 break;
[email protected]9f49afb2012-02-16 09:59:20717 drainable->DidConsume(rv);
[email protected]4c2048a2009-03-24 21:02:01718 total_bytes_written += rv;
719 }
720
721 EXPECT_EQ(kTestDataSize, total_bytes_written);
722
[email protected]aab1b9e2012-11-06 00:29:51723 rv = stream->Seek(FROM_BEGIN, 0, callback64.callback());
[email protected]cf02541b2012-04-11 08:02:17724 ASSERT_EQ(ERR_IO_PENDING, rv);
725 offset = callback64.WaitForResult();
[email protected]4c2048a2009-03-24 21:02:01726 EXPECT_EQ(0, offset);
727
728 int total_bytes_read = 0;
729
730 std::string data_read;
731 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20732 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
[email protected]aab1b9e2012-11-06 00:29:51733 rv = stream->Read(buf, buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07734 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01735 rv = callback.WaitForResult();
736 EXPECT_LE(0, rv);
737 if (rv <= 0)
738 break;
739 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20740 data_read.append(buf->data(), rv);
[email protected]4c2048a2009-03-24 21:02:01741 }
[email protected]aab1b9e2012-11-06 00:29:51742 stream.reset();
[email protected]4c2048a2009-03-24 21:02:01743
744 ok = file_util::GetFileSize(temp_file_path(), &file_size);
745 EXPECT_TRUE(ok);
746 EXPECT_EQ(kTestDataSize * 2, file_size);
747
748 EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
749 const std::string kExpectedFileData =
750 std::string(kTestData) + std::string(kTestData);
751 EXPECT_EQ(kExpectedFileData, data_read);
752}
753
[email protected]5eb431e22011-10-12 08:51:38754class TestWriteReadCompletionCallback {
[email protected]4c2048a2009-03-24 21:02:01755 public:
[email protected]5eb431e22011-10-12 08:51:38756 TestWriteReadCompletionCallback(
[email protected]8effd3f62011-03-25 16:29:07757 FileStream* stream,
[email protected]4c2048a2009-03-24 21:02:01758 int* total_bytes_written,
759 int* total_bytes_read,
760 std::string* data_read)
761 : result_(0),
762 have_result_(false),
763 waiting_for_result_(false),
764 stream_(stream),
765 total_bytes_written_(total_bytes_written),
766 total_bytes_read_(total_bytes_read),
[email protected]5eb431e22011-10-12 08:51:38767 data_read_(data_read),
768 callback_(base::Bind(&TestWriteReadCompletionCallback::OnComplete,
[email protected]9f49afb2012-02-16 09:59:20769 base::Unretained(this))),
770 test_data_(CreateTestDataBuffer()),
771 drainable_(new DrainableIOBuffer(test_data_, kTestDataSize)) {
772 }
[email protected]4c2048a2009-03-24 21:02:01773
774 int WaitForResult() {
775 DCHECK(!waiting_for_result_);
776 while (!have_result_) {
777 waiting_for_result_ = true;
778 MessageLoop::current()->Run();
779 waiting_for_result_ = false;
780 }
781 have_result_ = false; // auto-reset for next callback
782 return result_;
783 }
784
[email protected]5eb431e22011-10-12 08:51:38785 const CompletionCallback& callback() const { return callback_; }
786
[email protected]4c2048a2009-03-24 21:02:01787 private:
[email protected]5eb431e22011-10-12 08:51:38788 void OnComplete(int result) {
789 DCHECK_LT(0, result);
790 *total_bytes_written_ += result;
[email protected]4c2048a2009-03-24 21:02:01791
792 int rv;
793
794 if (*total_bytes_written_ != kTestDataSize) {
795 // Recurse to finish writing all data.
796 int total_bytes_written = 0, total_bytes_read = 0;
797 std::string data_read;
[email protected]5eb431e22011-10-12 08:51:38798 TestWriteReadCompletionCallback callback(
[email protected]4c2048a2009-03-24 21:02:01799 stream_, &total_bytes_written, &total_bytes_read, &data_read);
[email protected]9f49afb2012-02-16 09:59:20800 rv = stream_->Write(drainable_, drainable_->BytesRemaining(),
[email protected]5eb431e22011-10-12 08:51:38801 callback.callback());
[email protected]8effd3f62011-03-25 16:29:07802 DCHECK_EQ(ERR_IO_PENDING, rv);
[email protected]4c2048a2009-03-24 21:02:01803 rv = callback.WaitForResult();
[email protected]9f49afb2012-02-16 09:59:20804 drainable_->DidConsume(total_bytes_written);
[email protected]4c2048a2009-03-24 21:02:01805 *total_bytes_written_ += total_bytes_written;
806 *total_bytes_read_ += total_bytes_read;
807 *data_read_ += data_read;
808 } else { // We're done writing all data. Start reading the data.
[email protected]cf02541b2012-04-11 08:02:17809 stream_->SeekSync(FROM_BEGIN, 0);
[email protected]4c2048a2009-03-24 21:02:01810
[email protected]5eb431e22011-10-12 08:51:38811 TestCompletionCallback callback;
[email protected]4c2048a2009-03-24 21:02:01812 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20813 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
814 rv = stream_->Read(buf, buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07815 if (rv == ERR_IO_PENDING) {
[email protected]b5717a42012-02-14 19:33:52816 MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
[email protected]4c2048a2009-03-24 21:02:01817 rv = callback.WaitForResult();
[email protected]4c2048a2009-03-24 21:02:01818 }
819 EXPECT_LE(0, rv);
820 if (rv <= 0)
821 break;
822 *total_bytes_read_ += rv;
[email protected]9f49afb2012-02-16 09:59:20823 data_read_->append(buf->data(), rv);
[email protected]4c2048a2009-03-24 21:02:01824 }
825 }
826
827 result_ = *total_bytes_written_;
828 have_result_ = true;
829 if (waiting_for_result_)
830 MessageLoop::current()->Quit();
831 }
832
833 int result_;
834 bool have_result_;
835 bool waiting_for_result_;
[email protected]8effd3f62011-03-25 16:29:07836 FileStream* stream_;
[email protected]4c2048a2009-03-24 21:02:01837 int* total_bytes_written_;
838 int* total_bytes_read_;
839 std::string* data_read_;
[email protected]5eb431e22011-10-12 08:51:38840 const CompletionCallback callback_;
[email protected]9f49afb2012-02-16 09:59:20841 scoped_refptr<IOBufferWithSize> test_data_;
842 scoped_refptr<DrainableIOBuffer> drainable_;
[email protected]4c2048a2009-03-24 21:02:01843
[email protected]5eb431e22011-10-12 08:51:38844 DISALLOW_COPY_AND_ASSIGN(TestWriteReadCompletionCallback);
[email protected]4c2048a2009-03-24 21:02:01845};
846
847TEST_F(FileStreamTest, AsyncWriteRead) {
848 int64 file_size;
849 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
850 EXPECT_TRUE(ok);
851
[email protected]aab1b9e2012-11-06 00:29:51852 scoped_ptr<FileStream> stream(new FileStream(NULL));
[email protected]4c2048a2009-03-24 21:02:01853 int flags = base::PLATFORM_FILE_OPEN |
854 base::PLATFORM_FILE_READ |
855 base::PLATFORM_FILE_WRITE |
856 base::PLATFORM_FILE_ASYNC;
[email protected]aab1b9e2012-11-06 00:29:51857 int rv = stream->OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07858 EXPECT_EQ(OK, rv);
[email protected]4c2048a2009-03-24 21:02:01859
[email protected]aab1b9e2012-11-06 00:29:51860 int64 total_bytes_avail = stream->Available();
[email protected]4c2048a2009-03-24 21:02:01861 EXPECT_EQ(file_size, total_bytes_avail);
862
[email protected]aab1b9e2012-11-06 00:29:51863 int64 offset = stream->SeekSync(FROM_END, 0);
[email protected]4c2048a2009-03-24 21:02:01864 EXPECT_EQ(offset, file_size);
865
866 int total_bytes_written = 0;
867 int total_bytes_read = 0;
868 std::string data_read;
[email protected]aab1b9e2012-11-06 00:29:51869 TestWriteReadCompletionCallback callback(stream.get(), &total_bytes_written,
[email protected]4c2048a2009-03-24 21:02:01870 &total_bytes_read, &data_read);
871
[email protected]9f49afb2012-02-16 09:59:20872 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
[email protected]aab1b9e2012-11-06 00:29:51873 rv = stream->Write(buf, buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07874 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01875 rv = callback.WaitForResult();
876 EXPECT_LT(0, rv);
877 EXPECT_EQ(kTestDataSize, total_bytes_written);
878
[email protected]aab1b9e2012-11-06 00:29:51879 stream.reset();
[email protected]4c2048a2009-03-24 21:02:01880
881 ok = file_util::GetFileSize(temp_file_path(), &file_size);
882 EXPECT_TRUE(ok);
883 EXPECT_EQ(kTestDataSize * 2, file_size);
884
885 EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
886 const std::string kExpectedFileData =
887 std::string(kTestData) + std::string(kTestData);
888 EXPECT_EQ(kExpectedFileData, data_read);
889}
890
[email protected]5eb431e22011-10-12 08:51:38891class TestWriteCloseCompletionCallback {
[email protected]4c2048a2009-03-24 21:02:01892 public:
[email protected]5eb431e22011-10-12 08:51:38893 TestWriteCloseCompletionCallback(FileStream* stream, int* total_bytes_written)
[email protected]4c2048a2009-03-24 21:02:01894 : result_(0),
895 have_result_(false),
896 waiting_for_result_(false),
897 stream_(stream),
[email protected]5eb431e22011-10-12 08:51:38898 total_bytes_written_(total_bytes_written),
899 callback_(base::Bind(&TestWriteCloseCompletionCallback::OnComplete,
[email protected]9f49afb2012-02-16 09:59:20900 base::Unretained(this))),
901 test_data_(CreateTestDataBuffer()),
902 drainable_(new DrainableIOBuffer(test_data_, kTestDataSize)) {
903 }
[email protected]4c2048a2009-03-24 21:02:01904
905 int WaitForResult() {
906 DCHECK(!waiting_for_result_);
907 while (!have_result_) {
908 waiting_for_result_ = true;
909 MessageLoop::current()->Run();
910 waiting_for_result_ = false;
911 }
912 have_result_ = false; // auto-reset for next callback
913 return result_;
914 }
915
[email protected]5eb431e22011-10-12 08:51:38916 const CompletionCallback& callback() const { return callback_; }
917
[email protected]4c2048a2009-03-24 21:02:01918 private:
[email protected]5eb431e22011-10-12 08:51:38919 void OnComplete(int result) {
920 DCHECK_LT(0, result);
921 *total_bytes_written_ += result;
[email protected]4c2048a2009-03-24 21:02:01922
923 int rv;
924
925 if (*total_bytes_written_ != kTestDataSize) {
926 // Recurse to finish writing all data.
927 int total_bytes_written = 0;
[email protected]5eb431e22011-10-12 08:51:38928 TestWriteCloseCompletionCallback callback(stream_, &total_bytes_written);
[email protected]9f49afb2012-02-16 09:59:20929 rv = stream_->Write(drainable_, drainable_->BytesRemaining(),
[email protected]5eb431e22011-10-12 08:51:38930 callback.callback());
[email protected]8effd3f62011-03-25 16:29:07931 DCHECK_EQ(ERR_IO_PENDING, rv);
[email protected]4c2048a2009-03-24 21:02:01932 rv = callback.WaitForResult();
[email protected]9f49afb2012-02-16 09:59:20933 drainable_->DidConsume(total_bytes_written);
[email protected]4c2048a2009-03-24 21:02:01934 *total_bytes_written_ += total_bytes_written;
[email protected]4c2048a2009-03-24 21:02:01935 }
936
937 result_ = *total_bytes_written_;
938 have_result_ = true;
939 if (waiting_for_result_)
940 MessageLoop::current()->Quit();
941 }
942
943 int result_;
944 bool have_result_;
945 bool waiting_for_result_;
[email protected]8effd3f62011-03-25 16:29:07946 FileStream* stream_;
[email protected]4c2048a2009-03-24 21:02:01947 int* total_bytes_written_;
[email protected]5eb431e22011-10-12 08:51:38948 const CompletionCallback callback_;
[email protected]9f49afb2012-02-16 09:59:20949 scoped_refptr<IOBufferWithSize> test_data_;
950 scoped_refptr<DrainableIOBuffer> drainable_;
[email protected]4c2048a2009-03-24 21:02:01951
[email protected]5eb431e22011-10-12 08:51:38952 DISALLOW_COPY_AND_ASSIGN(TestWriteCloseCompletionCallback);
[email protected]4c2048a2009-03-24 21:02:01953};
954
955TEST_F(FileStreamTest, AsyncWriteClose) {
956 int64 file_size;
957 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
958 EXPECT_TRUE(ok);
959
[email protected]aab1b9e2012-11-06 00:29:51960 scoped_ptr<FileStream> stream(new FileStream(NULL));
[email protected]4c2048a2009-03-24 21:02:01961 int flags = base::PLATFORM_FILE_OPEN |
962 base::PLATFORM_FILE_READ |
963 base::PLATFORM_FILE_WRITE |
964 base::PLATFORM_FILE_ASYNC;
[email protected]aab1b9e2012-11-06 00:29:51965 int rv = stream->OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07966 EXPECT_EQ(OK, rv);
[email protected]4c2048a2009-03-24 21:02:01967
[email protected]aab1b9e2012-11-06 00:29:51968 int64 total_bytes_avail = stream->Available();
[email protected]4c2048a2009-03-24 21:02:01969 EXPECT_EQ(file_size, total_bytes_avail);
970
[email protected]aab1b9e2012-11-06 00:29:51971 int64 offset = stream->SeekSync(FROM_END, 0);
[email protected]4c2048a2009-03-24 21:02:01972 EXPECT_EQ(offset, file_size);
973
974 int total_bytes_written = 0;
[email protected]aab1b9e2012-11-06 00:29:51975 TestWriteCloseCompletionCallback callback(stream.get(), &total_bytes_written);
[email protected]4c2048a2009-03-24 21:02:01976
[email protected]9f49afb2012-02-16 09:59:20977 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
[email protected]aab1b9e2012-11-06 00:29:51978 rv = stream->Write(buf, buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07979 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01980 total_bytes_written = callback.WaitForResult();
981 EXPECT_LT(0, total_bytes_written);
982 EXPECT_EQ(kTestDataSize, total_bytes_written);
983
[email protected]aab1b9e2012-11-06 00:29:51984 stream.reset();
985
[email protected]4c2048a2009-03-24 21:02:01986 ok = file_util::GetFileSize(temp_file_path(), &file_size);
987 EXPECT_TRUE(ok);
988 EXPECT_EQ(kTestDataSize * 2, file_size);
989}
990
[email protected]0643a492009-03-09 15:49:20991// Tests truncating a file.
992TEST_F(FileStreamTest, Truncate) {
993 int flags = base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE;
994
[email protected]aab1b9e2012-11-06 00:29:51995 scoped_ptr<FileStream> write_stream(new FileStream(NULL));
996 ASSERT_EQ(OK, write_stream->OpenSync(temp_file_path(), flags));
[email protected]0643a492009-03-09 15:49:20997
998 // Write some data to the file.
999 const char test_data[] = "0123456789";
[email protected]aab1b9e2012-11-06 00:29:511000 write_stream->WriteSync(test_data, arraysize(test_data));
[email protected]0643a492009-03-09 15:49:201001
1002 // Truncate the file.
[email protected]aab1b9e2012-11-06 00:29:511003 ASSERT_EQ(4, write_stream->Truncate(4));
[email protected]0643a492009-03-09 15:49:201004
1005 // Write again.
[email protected]aab1b9e2012-11-06 00:29:511006 write_stream->WriteSync(test_data, 4);
[email protected]0643a492009-03-09 15:49:201007
1008 // Close the stream.
[email protected]aab1b9e2012-11-06 00:29:511009 write_stream.reset();
[email protected]0643a492009-03-09 15:49:201010
1011 // Read in the contents and make sure we get back what we expected.
1012 std::string read_contents;
[email protected]3fc364f92009-08-06 22:35:131013 EXPECT_TRUE(file_util::ReadFileToString(temp_file_path(), &read_contents));
[email protected]0643a492009-03-09 15:49:201014
[email protected]4c2048a2009-03-24 21:02:011015 EXPECT_EQ("01230123", read_contents);
[email protected]0643a492009-03-09 15:49:201016}
1017
[email protected]dbb747c2012-02-29 19:29:471018TEST_F(FileStreamTest, AsyncOpenAndDelete) {
1019 scoped_ptr<FileStream> stream(new FileStream(NULL));
1020 int flags = base::PLATFORM_FILE_OPEN |
1021 base::PLATFORM_FILE_WRITE |
1022 base::PLATFORM_FILE_ASYNC;
1023 TestCompletionCallback open_callback;
1024 int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
1025 EXPECT_EQ(ERR_IO_PENDING, rv);
1026
1027 // Delete the stream without waiting for the open operation to be
1028 // complete. Should be safe.
1029 stream.reset();
1030 // open_callback won't be called.
[email protected]aab1b9e2012-11-06 00:29:511031 MessageLoop::current()->RunUntilIdle();
[email protected]dbb747c2012-02-29 19:29:471032 EXPECT_FALSE(open_callback.have_result());
1033}
1034
[email protected]4c2048a2009-03-24 21:02:011035} // namespace
[email protected]96d73822011-10-10 02:11:241036
[email protected]8effd3f62011-03-25 16:29:071037} // namespace net