blob: 8f972ee94e10a563b67d08eca6f70cb7a75bfcd1 [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]e3d66fde2012-02-17 22:10:3436// This NetLog is used for notifying when a file stream is closed
37// (i.e. TYPE_FILE_STREAM_CLOSE event is recorded).
38class NetLogForNotifyingFileClosure : public NetLog {
39 public:
40 NetLogForNotifyingFileClosure()
41 : id_(0),
42 on_closure_(false /* manual_reset */, false /* initially_signaled */) {
43 }
44
45 // Wait until a file closure event is recorded.
46 bool WaitForClosure() {
47 const base::TimeDelta timeout(
48 base::TimeDelta::FromMilliseconds(
49 TestTimeouts::action_max_timeout_ms()));
50 return on_closure_.TimedWait(timeout);
51 }
52
53 // NetLog overrides:
54 virtual void AddEntry(EventType type,
55 const base::TimeTicks& time,
56 const Source& source,
57 EventPhase phase,
58 EventParameters* extra_parameters) {
59 if (type == TYPE_FILE_STREAM_CLOSE) {
60 on_closure_.Signal();
61 }
62 }
63
64 virtual uint32 NextID() { return id_++; }
65 virtual LogLevel GetLogLevel() const { return LOG_ALL; }
66 virtual void AddThreadSafeObserver(ThreadSafeObserver* observer) {}
67 virtual void RemoveThreadSafeObserver(ThreadSafeObserver* observer) {};
68
69
70 private:
71 uint32 id_;
72 base::WaitableEvent on_closure_;
73};
74
[email protected]96d73822011-10-10 02:11:2475} // namespace
76
[email protected]21da6eb2008-11-03 17:18:1477class FileStreamTest : public PlatformTest {
78 public:
79 virtual void SetUp() {
80 PlatformTest::SetUp();
81
[email protected]33edeab2009-08-18 16:07:5582 file_util::CreateTemporaryFile(&temp_file_path_);
[email protected]7ff3f632009-10-13 18:43:3583 file_util::WriteFile(temp_file_path_, kTestData, kTestDataSize);
[email protected]21da6eb2008-11-03 17:18:1484 }
85 virtual void TearDown() {
86 file_util::Delete(temp_file_path_, false);
87
88 PlatformTest::TearDown();
89 }
[email protected]96d73822011-10-10 02:11:2490
[email protected]07167e8f2009-01-26 21:38:1191 const FilePath temp_file_path() const { return temp_file_path_; }
[email protected]96d73822011-10-10 02:11:2492
[email protected]21da6eb2008-11-03 17:18:1493 private:
[email protected]07167e8f2009-01-26 21:38:1194 FilePath temp_file_path_;
[email protected]21da6eb2008-11-03 17:18:1495};
96
[email protected]96d73822011-10-10 02:11:2497namespace {
98
[email protected]21da6eb2008-11-03 17:18:1499TEST_F(FileStreamTest, BasicOpenClose) {
[email protected]96d73822011-10-10 02:11:24100 base::PlatformFile file = base::kInvalidPlatformFileValue;
101 {
[email protected]10342992012-02-02 18:49:43102 FileStream stream(NULL);
[email protected]fe57eb22012-02-09 05:59:40103 int rv = stream.OpenSync(temp_file_path(),
[email protected]96d73822011-10-10 02:11:24104 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ);
105 EXPECT_EQ(OK, rv);
106 EXPECT_TRUE(stream.IsOpen());
[email protected]84e0309f2012-02-24 01:56:59107 file = stream.GetPlatformFileForTesting();
[email protected]96d73822011-10-10 02:11:24108 }
109 EXPECT_NE(base::kInvalidPlatformFileValue, file);
110 base::PlatformFileInfo info;
111 // The file should be closed.
112 EXPECT_FALSE(base::GetPlatformFileInfo(file, &info));
113}
114
115TEST_F(FileStreamTest, FileHandleLeftOpen) {
116 bool created = false;
117 ASSERT_EQ(kTestDataSize,
118 file_util::WriteFile(temp_file_path(), kTestData, kTestDataSize));
119 int flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_READ;
120 base::PlatformFile file = base::CreatePlatformFile(
121 temp_file_path(), flags, &created, NULL);
122
123 {
124 // Seek to the beginning of the file and read.
[email protected]10342992012-02-02 18:49:43125 FileStream read_stream(file, flags, NULL);
[email protected]96d73822011-10-10 02:11:24126 EXPECT_TRUE(read_stream.IsOpen());
127 }
128
129 EXPECT_NE(base::kInvalidPlatformFileValue, file);
130 base::PlatformFileInfo info;
131 // The file should still be open.
132 EXPECT_TRUE(base::GetPlatformFileInfo(file, &info));
133 // Clean up.
134 EXPECT_TRUE(base::ClosePlatformFile(file));
[email protected]21da6eb2008-11-03 17:18:14135}
136
[email protected]92aad5222009-02-09 22:26:41137// Test the use of FileStream with a file handle provided at construction.
138TEST_F(FileStreamTest, UseFileHandle) {
139 bool created = false;
140
141 // 1. Test reading with a file handle.
142 ASSERT_EQ(kTestDataSize,
143 file_util::WriteFile(temp_file_path(), kTestData, kTestDataSize));
144 int flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_READ;
145 base::PlatformFile file = base::CreatePlatformFile(
[email protected]ed65fec2010-08-31 19:30:27146 temp_file_path(), flags, &created, NULL);
[email protected]92aad5222009-02-09 22:26:41147
148 // Seek to the beginning of the file and read.
[email protected]10342992012-02-02 18:49:43149 FileStream read_stream(file, flags, NULL);
[email protected]8effd3f62011-03-25 16:29:07150 ASSERT_EQ(0, read_stream.Seek(FROM_BEGIN, 0));
[email protected]92aad5222009-02-09 22:26:41151 ASSERT_EQ(kTestDataSize, read_stream.Available());
152 // Read into buffer and compare.
153 char buffer[kTestDataSize];
[email protected]5eb431e22011-10-12 08:51:38154 ASSERT_EQ(kTestDataSize,
[email protected]6b230f42012-02-15 04:08:41155 read_stream.ReadSync(buffer, kTestDataSize));
[email protected]92aad5222009-02-09 22:26:41156 ASSERT_EQ(0, memcmp(kTestData, buffer, kTestDataSize));
[email protected]fe57eb22012-02-09 05:59:40157 read_stream.CloseSync();
[email protected]92aad5222009-02-09 22:26:41158
159 // 2. Test writing with a file handle.
160 file_util::Delete(temp_file_path(), false);
161 flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_WRITE;
[email protected]ed65fec2010-08-31 19:30:27162 file = base::CreatePlatformFile(temp_file_path(), flags, &created, NULL);
[email protected]92aad5222009-02-09 22:26:41163
[email protected]10342992012-02-02 18:49:43164 FileStream write_stream(file, flags, NULL);
[email protected]8effd3f62011-03-25 16:29:07165 ASSERT_EQ(0, write_stream.Seek(FROM_BEGIN, 0));
[email protected]5eb431e22011-10-12 08:51:38166 ASSERT_EQ(kTestDataSize,
[email protected]6b230f42012-02-15 04:08:41167 write_stream.WriteSync(kTestData, kTestDataSize));
[email protected]fe57eb22012-02-09 05:59:40168 write_stream.CloseSync();
[email protected]92aad5222009-02-09 22:26:41169
170 // Read into buffer and compare to make sure the handle worked fine.
171 ASSERT_EQ(kTestDataSize,
172 file_util::ReadFile(temp_file_path(), buffer, kTestDataSize));
173 ASSERT_EQ(0, memcmp(kTestData, buffer, kTestDataSize));
174}
175
[email protected]21da6eb2008-11-03 17:18:14176TEST_F(FileStreamTest, UseClosedStream) {
[email protected]10342992012-02-02 18:49:43177 FileStream stream(NULL);
[email protected]21da6eb2008-11-03 17:18:14178
179 EXPECT_FALSE(stream.IsOpen());
180
181 // Try seeking...
[email protected]8effd3f62011-03-25 16:29:07182 int64 new_offset = stream.Seek(FROM_BEGIN, 5);
183 EXPECT_EQ(ERR_UNEXPECTED, new_offset);
[email protected]21da6eb2008-11-03 17:18:14184
185 // Try available...
186 int64 avail = stream.Available();
[email protected]8effd3f62011-03-25 16:29:07187 EXPECT_EQ(ERR_UNEXPECTED, avail);
[email protected]21da6eb2008-11-03 17:18:14188
189 // Try reading...
190 char buf[10];
[email protected]6b230f42012-02-15 04:08:41191 int rv = stream.ReadSync(buf, arraysize(buf));
[email protected]8effd3f62011-03-25 16:29:07192 EXPECT_EQ(ERR_UNEXPECTED, rv);
[email protected]21da6eb2008-11-03 17:18:14193}
194
195TEST_F(FileStreamTest, BasicRead) {
196 int64 file_size;
197 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
198 EXPECT_TRUE(ok);
199
[email protected]10342992012-02-02 18:49:43200 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38201 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14202 base::PLATFORM_FILE_READ;
[email protected]fe57eb22012-02-09 05:59:40203 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07204 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14205
206 int64 total_bytes_avail = stream.Available();
207 EXPECT_EQ(file_size, total_bytes_avail);
208
[email protected]4c2048a2009-03-24 21:02:01209 int total_bytes_read = 0;
[email protected]21da6eb2008-11-03 17:18:14210
211 std::string data_read;
212 for (;;) {
213 char buf[4];
[email protected]6b230f42012-02-15 04:08:41214 rv = stream.ReadSync(buf, arraysize(buf));
[email protected]21da6eb2008-11-03 17:18:14215 EXPECT_LE(0, rv);
216 if (rv <= 0)
217 break;
218 total_bytes_read += rv;
219 data_read.append(buf, rv);
220 }
221 EXPECT_EQ(file_size, total_bytes_read);
[email protected]4c2048a2009-03-24 21:02:01222 EXPECT_EQ(kTestData, data_read);
[email protected]21da6eb2008-11-03 17:18:14223}
224
225TEST_F(FileStreamTest, AsyncRead) {
226 int64 file_size;
227 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
228 EXPECT_TRUE(ok);
229
[email protected]10342992012-02-02 18:49:43230 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38231 int flags = base::PLATFORM_FILE_OPEN |
232 base::PLATFORM_FILE_READ |
[email protected]21da6eb2008-11-03 17:18:14233 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:40234 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07235 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14236
237 int64 total_bytes_avail = stream.Available();
238 EXPECT_EQ(file_size, total_bytes_avail);
239
[email protected]5eb431e22011-10-12 08:51:38240 TestCompletionCallback callback;
[email protected]21da6eb2008-11-03 17:18:14241
[email protected]4c2048a2009-03-24 21:02:01242 int total_bytes_read = 0;
[email protected]21da6eb2008-11-03 17:18:14243
244 std::string data_read;
245 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20246 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
247 rv = stream.Read(buf, buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07248 if (rv == ERR_IO_PENDING)
[email protected]21da6eb2008-11-03 17:18:14249 rv = callback.WaitForResult();
250 EXPECT_LE(0, rv);
251 if (rv <= 0)
252 break;
253 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20254 data_read.append(buf->data(), rv);
[email protected]21da6eb2008-11-03 17:18:14255 }
256 EXPECT_EQ(file_size, total_bytes_read);
[email protected]4c2048a2009-03-24 21:02:01257 EXPECT_EQ(kTestData, data_read);
258}
259
260TEST_F(FileStreamTest, AsyncRead_EarlyClose) {
261 int64 file_size;
262 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
263 EXPECT_TRUE(ok);
264
[email protected]10342992012-02-02 18:49:43265 FileStream stream(NULL);
[email protected]4c2048a2009-03-24 21:02:01266 int flags = base::PLATFORM_FILE_OPEN |
267 base::PLATFORM_FILE_READ |
268 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:40269 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07270 EXPECT_EQ(OK, rv);
[email protected]4c2048a2009-03-24 21:02:01271
272 int64 total_bytes_avail = stream.Available();
273 EXPECT_EQ(file_size, total_bytes_avail);
274
[email protected]5eb431e22011-10-12 08:51:38275 TestCompletionCallback callback;
[email protected]4c2048a2009-03-24 21:02:01276
[email protected]9f49afb2012-02-16 09:59:20277 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
278 rv = stream.Read(buf, buf->size(), callback.callback());
[email protected]fe57eb22012-02-09 05:59:40279 stream.CloseSync();
[email protected]3828a752009-06-03 23:05:59280 if (rv < 0) {
[email protected]8effd3f62011-03-25 16:29:07281 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3828a752009-06-03 23:05:59282 // The callback should not be called if the request is cancelled.
283 MessageLoop::current()->RunAllPending();
284 EXPECT_FALSE(callback.have_result());
285 } else {
[email protected]9f49afb2012-02-16 09:59:20286 EXPECT_EQ(std::string(kTestData, rv), std::string(buf->data(), rv));
[email protected]3828a752009-06-03 23:05:59287 }
[email protected]21da6eb2008-11-03 17:18:14288}
289
[email protected]06b802b2012-02-22 03:34:54290// Similar to AsyncRead_EarlyClose but deletes a stream instead, to ensure
291// that deleting a stream is safe while an async read is in flight.
292TEST_F(FileStreamTest, AsyncRead_EarlyDelete) {
293 int64 file_size;
294 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
295 EXPECT_TRUE(ok);
296
297 scoped_ptr<FileStream> stream(new FileStream(NULL));
298 int flags = base::PLATFORM_FILE_OPEN |
299 base::PLATFORM_FILE_READ |
300 base::PLATFORM_FILE_ASYNC;
301 TestCompletionCallback callback;
302 int rv = stream->Open(temp_file_path(), flags, callback.callback());
303 EXPECT_EQ(ERR_IO_PENDING, rv);
304 EXPECT_EQ(OK, callback.WaitForResult());
305
306 int64 total_bytes_avail = stream->Available();
307 EXPECT_EQ(file_size, total_bytes_avail);
308
309 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
310 rv = stream->Read(buf, buf->size(), callback.callback());
311 stream.reset(); // Delete instead of closing it.
312 if (rv < 0) {
313 EXPECT_EQ(ERR_IO_PENDING, rv);
314 // The callback should not be called if the request is cancelled.
315 MessageLoop::current()->RunAllPending();
316 EXPECT_FALSE(callback.have_result());
317 } else {
318 EXPECT_EQ(std::string(kTestData, rv), std::string(buf->data(), rv));
319 }
320}
321
[email protected]21da6eb2008-11-03 17:18:14322TEST_F(FileStreamTest, BasicRead_FromOffset) {
323 int64 file_size;
324 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
325 EXPECT_TRUE(ok);
326
[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]8effd3f62011-03-25 16:29:07334 int64 new_offset = stream.Seek(FROM_BEGIN, kOffset);
[email protected]21da6eb2008-11-03 17:18:14335 EXPECT_EQ(kOffset, new_offset);
336
337 int64 total_bytes_avail = stream.Available();
338 EXPECT_EQ(file_size - kOffset, total_bytes_avail);
339
340 int64 total_bytes_read = 0;
341
342 std::string data_read;
343 for (;;) {
344 char buf[4];
[email protected]6b230f42012-02-15 04:08:41345 rv = stream.ReadSync(buf, arraysize(buf));
[email protected]21da6eb2008-11-03 17:18:14346 EXPECT_LE(0, rv);
347 if (rv <= 0)
348 break;
349 total_bytes_read += rv;
350 data_read.append(buf, rv);
351 }
352 EXPECT_EQ(file_size - kOffset, total_bytes_read);
353 EXPECT_TRUE(data_read == kTestData + kOffset);
[email protected]4c2048a2009-03-24 21:02:01354 EXPECT_EQ(kTestData + kOffset, data_read);
[email protected]21da6eb2008-11-03 17:18:14355}
356
357TEST_F(FileStreamTest, AsyncRead_FromOffset) {
358 int64 file_size;
359 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
360 EXPECT_TRUE(ok);
361
[email protected]10342992012-02-02 18:49:43362 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38363 int flags = base::PLATFORM_FILE_OPEN |
364 base::PLATFORM_FILE_READ |
[email protected]21da6eb2008-11-03 17:18:14365 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:40366 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07367 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14368
369 const int64 kOffset = 3;
[email protected]8effd3f62011-03-25 16:29:07370 int64 new_offset = stream.Seek(FROM_BEGIN, kOffset);
[email protected]21da6eb2008-11-03 17:18:14371 EXPECT_EQ(kOffset, new_offset);
372
373 int64 total_bytes_avail = stream.Available();
374 EXPECT_EQ(file_size - kOffset, total_bytes_avail);
375
[email protected]5eb431e22011-10-12 08:51:38376 TestCompletionCallback callback;
[email protected]21da6eb2008-11-03 17:18:14377
[email protected]4c2048a2009-03-24 21:02:01378 int total_bytes_read = 0;
[email protected]21da6eb2008-11-03 17:18:14379
380 std::string data_read;
381 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20382 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
383 rv = stream.Read(buf, buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07384 if (rv == ERR_IO_PENDING)
[email protected]21da6eb2008-11-03 17:18:14385 rv = callback.WaitForResult();
386 EXPECT_LE(0, rv);
387 if (rv <= 0)
388 break;
389 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20390 data_read.append(buf->data(), rv);
[email protected]21da6eb2008-11-03 17:18:14391 }
392 EXPECT_EQ(file_size - kOffset, total_bytes_read);
[email protected]4c2048a2009-03-24 21:02:01393 EXPECT_EQ(kTestData + kOffset, data_read);
[email protected]21da6eb2008-11-03 17:18:14394}
395
396TEST_F(FileStreamTest, SeekAround) {
[email protected]10342992012-02-02 18:49:43397 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38398 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14399 base::PLATFORM_FILE_READ;
[email protected]fe57eb22012-02-09 05:59:40400 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07401 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14402
403 const int64 kOffset = 3;
[email protected]8effd3f62011-03-25 16:29:07404 int64 new_offset = stream.Seek(FROM_BEGIN, kOffset);
[email protected]21da6eb2008-11-03 17:18:14405 EXPECT_EQ(kOffset, new_offset);
406
[email protected]8effd3f62011-03-25 16:29:07407 new_offset = stream.Seek(FROM_CURRENT, kOffset);
[email protected]21da6eb2008-11-03 17:18:14408 EXPECT_EQ(2 * kOffset, new_offset);
409
[email protected]8effd3f62011-03-25 16:29:07410 new_offset = stream.Seek(FROM_CURRENT, -kOffset);
[email protected]21da6eb2008-11-03 17:18:14411 EXPECT_EQ(kOffset, new_offset);
412
413 const int kTestDataLen = arraysize(kTestData) - 1;
414
[email protected]8effd3f62011-03-25 16:29:07415 new_offset = stream.Seek(FROM_END, -kTestDataLen);
[email protected]21da6eb2008-11-03 17:18:14416 EXPECT_EQ(0, new_offset);
417}
418
419TEST_F(FileStreamTest, BasicWrite) {
[email protected]10342992012-02-02 18:49:43420 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38421 int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
[email protected]21da6eb2008-11-03 17:18:14422 base::PLATFORM_FILE_WRITE;
[email protected]fe57eb22012-02-09 05:59:40423 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07424 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14425
426 int64 file_size;
427 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
428 EXPECT_TRUE(ok);
429 EXPECT_EQ(0, file_size);
430
[email protected]6b230f42012-02-15 04:08:41431 rv = stream.WriteSync(kTestData, kTestDataSize);
[email protected]21da6eb2008-11-03 17:18:14432 EXPECT_EQ(kTestDataSize, rv);
[email protected]fe57eb22012-02-09 05:59:40433 stream.CloseSync();
[email protected]21da6eb2008-11-03 17:18:14434
435 ok = file_util::GetFileSize(temp_file_path(), &file_size);
436 EXPECT_TRUE(ok);
437 EXPECT_EQ(kTestDataSize, file_size);
438}
439
440TEST_F(FileStreamTest, AsyncWrite) {
[email protected]10342992012-02-02 18:49:43441 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38442 int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
443 base::PLATFORM_FILE_WRITE |
[email protected]21da6eb2008-11-03 17:18:14444 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:40445 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07446 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14447
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 int total_bytes_written = 0;
[email protected]21da6eb2008-11-03 17:18:14455
[email protected]9f49afb2012-02-16 09:59:20456 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
457 scoped_refptr<DrainableIOBuffer> drainable =
458 new DrainableIOBuffer(buf, buf->size());
[email protected]21da6eb2008-11-03 17:18:14459 while (total_bytes_written != kTestDataSize) {
[email protected]9f49afb2012-02-16 09:59:20460 rv = stream.Write(drainable, drainable->BytesRemaining(),
[email protected]5eb431e22011-10-12 08:51:38461 callback.callback());
[email protected]8effd3f62011-03-25 16:29:07462 if (rv == ERR_IO_PENDING)
[email protected]21da6eb2008-11-03 17:18:14463 rv = callback.WaitForResult();
464 EXPECT_LT(0, rv);
465 if (rv <= 0)
466 break;
[email protected]9f49afb2012-02-16 09:59:20467 drainable->DidConsume(rv);
[email protected]21da6eb2008-11-03 17:18:14468 total_bytes_written += rv;
469 }
470 ok = file_util::GetFileSize(temp_file_path(), &file_size);
471 EXPECT_TRUE(ok);
472 EXPECT_EQ(file_size, total_bytes_written);
473}
474
[email protected]4c2048a2009-03-24 21:02:01475TEST_F(FileStreamTest, AsyncWrite_EarlyClose) {
[email protected]10342992012-02-02 18:49:43476 FileStream stream(NULL);
[email protected]4c2048a2009-03-24 21:02:01477 int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
478 base::PLATFORM_FILE_WRITE |
479 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:40480 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07481 EXPECT_EQ(OK, rv);
[email protected]4c2048a2009-03-24 21:02:01482
483 int64 file_size;
484 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
485 EXPECT_TRUE(ok);
486 EXPECT_EQ(0, file_size);
487
[email protected]5eb431e22011-10-12 08:51:38488 TestCompletionCallback callback;
[email protected]4c2048a2009-03-24 21:02:01489
[email protected]9f49afb2012-02-16 09:59:20490 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
491 rv = stream.Write(buf, buf->size(), callback.callback());
[email protected]fe57eb22012-02-09 05:59:40492 stream.CloseSync();
[email protected]3828a752009-06-03 23:05:59493 if (rv < 0) {
[email protected]8effd3f62011-03-25 16:29:07494 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3828a752009-06-03 23:05:59495 // The callback should not be called if the request is cancelled.
496 MessageLoop::current()->RunAllPending();
497 EXPECT_FALSE(callback.have_result());
498 } else {
499 ok = file_util::GetFileSize(temp_file_path(), &file_size);
500 EXPECT_TRUE(ok);
501 EXPECT_EQ(file_size, rv);
502 }
[email protected]4c2048a2009-03-24 21:02:01503}
504
[email protected]21da6eb2008-11-03 17:18:14505TEST_F(FileStreamTest, BasicWrite_FromOffset) {
[email protected]10342992012-02-02 18:49:43506 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38507 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14508 base::PLATFORM_FILE_WRITE;
[email protected]fe57eb22012-02-09 05:59:40509 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07510 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14511
512 int64 file_size;
513 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
514 EXPECT_TRUE(ok);
515 EXPECT_EQ(kTestDataSize, file_size);
516
517 const int64 kOffset = 0;
[email protected]8effd3f62011-03-25 16:29:07518 int64 new_offset = stream.Seek(FROM_END, kOffset);
[email protected]21da6eb2008-11-03 17:18:14519 EXPECT_EQ(kTestDataSize, new_offset);
520
[email protected]6b230f42012-02-15 04:08:41521 rv = stream.WriteSync(kTestData, kTestDataSize);
[email protected]21da6eb2008-11-03 17:18:14522 EXPECT_EQ(kTestDataSize, rv);
[email protected]fe57eb22012-02-09 05:59:40523 stream.CloseSync();
[email protected]21da6eb2008-11-03 17:18:14524
525 ok = file_util::GetFileSize(temp_file_path(), &file_size);
526 EXPECT_TRUE(ok);
527 EXPECT_EQ(kTestDataSize * 2, file_size);
528}
529
530TEST_F(FileStreamTest, AsyncWrite_FromOffset) {
531 int64 file_size;
532 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
533 EXPECT_TRUE(ok);
534
[email protected]10342992012-02-02 18:49:43535 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38536 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14537 base::PLATFORM_FILE_WRITE |
538 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:40539 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07540 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14541
542 const int64 kOffset = 0;
[email protected]8effd3f62011-03-25 16:29:07543 int64 new_offset = stream.Seek(FROM_END, kOffset);
[email protected]21da6eb2008-11-03 17:18:14544 EXPECT_EQ(kTestDataSize, new_offset);
545
[email protected]5eb431e22011-10-12 08:51:38546 TestCompletionCallback callback;
[email protected]4c2048a2009-03-24 21:02:01547 int total_bytes_written = 0;
[email protected]21da6eb2008-11-03 17:18:14548
[email protected]9f49afb2012-02-16 09:59:20549 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
550 scoped_refptr<DrainableIOBuffer> drainable =
551 new DrainableIOBuffer(buf, buf->size());
[email protected]21da6eb2008-11-03 17:18:14552 while (total_bytes_written != kTestDataSize) {
[email protected]9f49afb2012-02-16 09:59:20553 rv = stream.Write(drainable, drainable->BytesRemaining(),
[email protected]5eb431e22011-10-12 08:51:38554 callback.callback());
[email protected]8effd3f62011-03-25 16:29:07555 if (rv == ERR_IO_PENDING)
[email protected]21da6eb2008-11-03 17:18:14556 rv = callback.WaitForResult();
557 EXPECT_LT(0, rv);
558 if (rv <= 0)
559 break;
[email protected]9f49afb2012-02-16 09:59:20560 drainable->DidConsume(rv);
[email protected]21da6eb2008-11-03 17:18:14561 total_bytes_written += rv;
562 }
563 ok = file_util::GetFileSize(temp_file_path(), &file_size);
564 EXPECT_TRUE(ok);
565 EXPECT_EQ(file_size, kTestDataSize * 2);
566}
567
568TEST_F(FileStreamTest, BasicReadWrite) {
569 int64 file_size;
570 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
571 EXPECT_TRUE(ok);
572
[email protected]10342992012-02-02 18:49:43573 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38574 int flags = base::PLATFORM_FILE_OPEN |
575 base::PLATFORM_FILE_READ |
[email protected]21da6eb2008-11-03 17:18:14576 base::PLATFORM_FILE_WRITE;
[email protected]fe57eb22012-02-09 05:59:40577 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07578 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14579
580 int64 total_bytes_avail = stream.Available();
581 EXPECT_EQ(file_size, total_bytes_avail);
582
[email protected]4c2048a2009-03-24 21:02:01583 int total_bytes_read = 0;
[email protected]21da6eb2008-11-03 17:18:14584
585 std::string data_read;
586 for (;;) {
587 char buf[4];
[email protected]6b230f42012-02-15 04:08:41588 rv = stream.ReadSync(buf, arraysize(buf));
[email protected]21da6eb2008-11-03 17:18:14589 EXPECT_LE(0, rv);
590 if (rv <= 0)
591 break;
592 total_bytes_read += rv;
593 data_read.append(buf, rv);
594 }
595 EXPECT_EQ(file_size, total_bytes_read);
596 EXPECT_TRUE(data_read == kTestData);
597
[email protected]6b230f42012-02-15 04:08:41598 rv = stream.WriteSync(kTestData, kTestDataSize);
[email protected]21da6eb2008-11-03 17:18:14599 EXPECT_EQ(kTestDataSize, rv);
[email protected]fe57eb22012-02-09 05:59:40600 stream.CloseSync();
[email protected]21da6eb2008-11-03 17:18:14601
602 ok = file_util::GetFileSize(temp_file_path(), &file_size);
603 EXPECT_TRUE(ok);
604 EXPECT_EQ(kTestDataSize * 2, file_size);
605}
606
[email protected]4c2048a2009-03-24 21:02:01607TEST_F(FileStreamTest, BasicWriteRead) {
608 int64 file_size;
609 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
610 EXPECT_TRUE(ok);
611
[email protected]10342992012-02-02 18:49:43612 FileStream stream(NULL);
[email protected]4c2048a2009-03-24 21:02:01613 int flags = base::PLATFORM_FILE_OPEN |
614 base::PLATFORM_FILE_READ |
615 base::PLATFORM_FILE_WRITE;
[email protected]fe57eb22012-02-09 05:59:40616 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07617 EXPECT_EQ(OK, rv);
[email protected]4c2048a2009-03-24 21:02:01618
619 int64 total_bytes_avail = stream.Available();
620 EXPECT_EQ(file_size, total_bytes_avail);
621
[email protected]8effd3f62011-03-25 16:29:07622 int64 offset = stream.Seek(FROM_END, 0);
[email protected]4c2048a2009-03-24 21:02:01623 EXPECT_EQ(offset, file_size);
624
[email protected]6b230f42012-02-15 04:08:41625 rv = stream.WriteSync(kTestData, kTestDataSize);
[email protected]4c2048a2009-03-24 21:02:01626 EXPECT_EQ(kTestDataSize, rv);
627
[email protected]8effd3f62011-03-25 16:29:07628 offset = stream.Seek(FROM_BEGIN, 0);
[email protected]4c2048a2009-03-24 21:02:01629 EXPECT_EQ(0, offset);
630
631 int64 total_bytes_read = 0;
632
633 std::string data_read;
634 for (;;) {
635 char buf[4];
[email protected]6b230f42012-02-15 04:08:41636 rv = stream.ReadSync(buf, arraysize(buf));
[email protected]4c2048a2009-03-24 21:02:01637 EXPECT_LE(0, rv);
638 if (rv <= 0)
639 break;
640 total_bytes_read += rv;
641 data_read.append(buf, rv);
642 }
[email protected]fe57eb22012-02-09 05:59:40643 stream.CloseSync();
[email protected]4c2048a2009-03-24 21:02:01644
645 ok = file_util::GetFileSize(temp_file_path(), &file_size);
646 EXPECT_TRUE(ok);
647 EXPECT_EQ(kTestDataSize * 2, file_size);
648 EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
649
650 const std::string kExpectedFileData =
651 std::string(kTestData) + std::string(kTestData);
652 EXPECT_EQ(kExpectedFileData, data_read);
653}
654
655TEST_F(FileStreamTest, BasicAsyncReadWrite) {
656 int64 file_size;
657 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
658 EXPECT_TRUE(ok);
659
[email protected]10342992012-02-02 18:49:43660 FileStream stream(NULL);
[email protected]4c2048a2009-03-24 21:02:01661 int flags = base::PLATFORM_FILE_OPEN |
662 base::PLATFORM_FILE_READ |
663 base::PLATFORM_FILE_WRITE |
664 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:40665 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07666 EXPECT_EQ(OK, rv);
[email protected]4c2048a2009-03-24 21:02:01667
668 int64 total_bytes_avail = stream.Available();
669 EXPECT_EQ(file_size, total_bytes_avail);
670
[email protected]5eb431e22011-10-12 08:51:38671 TestCompletionCallback callback;
[email protected]4c2048a2009-03-24 21:02:01672 int64 total_bytes_read = 0;
673
674 std::string data_read;
675 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20676 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
677 rv = stream.Read(buf, buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07678 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01679 rv = callback.WaitForResult();
680 EXPECT_LE(0, rv);
681 if (rv <= 0)
682 break;
683 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20684 data_read.append(buf->data(), rv);
[email protected]4c2048a2009-03-24 21:02:01685 }
686 EXPECT_EQ(file_size, total_bytes_read);
687 EXPECT_TRUE(data_read == kTestData);
688
689 int total_bytes_written = 0;
690
[email protected]9f49afb2012-02-16 09:59:20691 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
692 scoped_refptr<DrainableIOBuffer> drainable =
693 new DrainableIOBuffer(buf, buf->size());
[email protected]4c2048a2009-03-24 21:02:01694 while (total_bytes_written != kTestDataSize) {
[email protected]9f49afb2012-02-16 09:59:20695 rv = stream.Write(drainable, drainable->BytesRemaining(),
[email protected]5eb431e22011-10-12 08:51:38696 callback.callback());
[email protected]8effd3f62011-03-25 16:29:07697 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01698 rv = callback.WaitForResult();
699 EXPECT_LT(0, rv);
700 if (rv <= 0)
701 break;
[email protected]9f49afb2012-02-16 09:59:20702 drainable->DidConsume(rv);
[email protected]4c2048a2009-03-24 21:02:01703 total_bytes_written += rv;
704 }
705
[email protected]fe57eb22012-02-09 05:59:40706 stream.CloseSync();
[email protected]4c2048a2009-03-24 21:02:01707
708 ok = file_util::GetFileSize(temp_file_path(), &file_size);
709 EXPECT_TRUE(ok);
710 EXPECT_EQ(kTestDataSize * 2, file_size);
711}
712
713TEST_F(FileStreamTest, BasicAsyncWriteRead) {
714 int64 file_size;
715 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
716 EXPECT_TRUE(ok);
717
[email protected]10342992012-02-02 18:49:43718 FileStream stream(NULL);
[email protected]4c2048a2009-03-24 21:02:01719 int flags = base::PLATFORM_FILE_OPEN |
720 base::PLATFORM_FILE_READ |
721 base::PLATFORM_FILE_WRITE |
722 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:40723 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07724 EXPECT_EQ(OK, rv);
[email protected]4c2048a2009-03-24 21:02:01725
726 int64 total_bytes_avail = stream.Available();
727 EXPECT_EQ(file_size, total_bytes_avail);
728
[email protected]8effd3f62011-03-25 16:29:07729 int64 offset = stream.Seek(FROM_END, 0);
[email protected]4c2048a2009-03-24 21:02:01730 EXPECT_EQ(offset, file_size);
731
[email protected]5eb431e22011-10-12 08:51:38732 TestCompletionCallback callback;
[email protected]4c2048a2009-03-24 21:02:01733 int total_bytes_written = 0;
734
[email protected]9f49afb2012-02-16 09:59:20735 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
736 scoped_refptr<DrainableIOBuffer> drainable =
737 new DrainableIOBuffer(buf, buf->size());
[email protected]4c2048a2009-03-24 21:02:01738 while (total_bytes_written != kTestDataSize) {
[email protected]9f49afb2012-02-16 09:59:20739 rv = stream.Write(drainable, drainable->BytesRemaining(),
[email protected]5eb431e22011-10-12 08:51:38740 callback.callback());
[email protected]8effd3f62011-03-25 16:29:07741 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01742 rv = callback.WaitForResult();
743 EXPECT_LT(0, rv);
744 if (rv <= 0)
745 break;
[email protected]9f49afb2012-02-16 09:59:20746 drainable->DidConsume(rv);
[email protected]4c2048a2009-03-24 21:02:01747 total_bytes_written += rv;
748 }
749
750 EXPECT_EQ(kTestDataSize, total_bytes_written);
751
[email protected]8effd3f62011-03-25 16:29:07752 offset = stream.Seek(FROM_BEGIN, 0);
[email protected]4c2048a2009-03-24 21:02:01753 EXPECT_EQ(0, offset);
754
755 int total_bytes_read = 0;
756
757 std::string data_read;
758 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20759 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
760 rv = stream.Read(buf, buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07761 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01762 rv = callback.WaitForResult();
763 EXPECT_LE(0, rv);
764 if (rv <= 0)
765 break;
766 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20767 data_read.append(buf->data(), rv);
[email protected]4c2048a2009-03-24 21:02:01768 }
[email protected]fe57eb22012-02-09 05:59:40769 stream.CloseSync();
[email protected]4c2048a2009-03-24 21:02:01770
771 ok = file_util::GetFileSize(temp_file_path(), &file_size);
772 EXPECT_TRUE(ok);
773 EXPECT_EQ(kTestDataSize * 2, file_size);
774
775 EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
776 const std::string kExpectedFileData =
777 std::string(kTestData) + std::string(kTestData);
778 EXPECT_EQ(kExpectedFileData, data_read);
779}
780
[email protected]5eb431e22011-10-12 08:51:38781class TestWriteReadCompletionCallback {
[email protected]4c2048a2009-03-24 21:02:01782 public:
[email protected]5eb431e22011-10-12 08:51:38783 TestWriteReadCompletionCallback(
[email protected]8effd3f62011-03-25 16:29:07784 FileStream* stream,
[email protected]4c2048a2009-03-24 21:02:01785 int* total_bytes_written,
786 int* total_bytes_read,
787 std::string* data_read)
788 : result_(0),
789 have_result_(false),
790 waiting_for_result_(false),
791 stream_(stream),
792 total_bytes_written_(total_bytes_written),
793 total_bytes_read_(total_bytes_read),
[email protected]5eb431e22011-10-12 08:51:38794 data_read_(data_read),
795 callback_(base::Bind(&TestWriteReadCompletionCallback::OnComplete,
[email protected]9f49afb2012-02-16 09:59:20796 base::Unretained(this))),
797 test_data_(CreateTestDataBuffer()),
798 drainable_(new DrainableIOBuffer(test_data_, kTestDataSize)) {
799 }
[email protected]4c2048a2009-03-24 21:02:01800
801 int WaitForResult() {
802 DCHECK(!waiting_for_result_);
803 while (!have_result_) {
804 waiting_for_result_ = true;
805 MessageLoop::current()->Run();
806 waiting_for_result_ = false;
807 }
808 have_result_ = false; // auto-reset for next callback
809 return result_;
810 }
811
[email protected]5eb431e22011-10-12 08:51:38812 const CompletionCallback& callback() const { return callback_; }
813
[email protected]4c2048a2009-03-24 21:02:01814 private:
[email protected]5eb431e22011-10-12 08:51:38815 void OnComplete(int result) {
816 DCHECK_LT(0, result);
817 *total_bytes_written_ += result;
[email protected]4c2048a2009-03-24 21:02:01818
819 int rv;
820
821 if (*total_bytes_written_ != kTestDataSize) {
822 // Recurse to finish writing all data.
823 int total_bytes_written = 0, total_bytes_read = 0;
824 std::string data_read;
[email protected]5eb431e22011-10-12 08:51:38825 TestWriteReadCompletionCallback callback(
[email protected]4c2048a2009-03-24 21:02:01826 stream_, &total_bytes_written, &total_bytes_read, &data_read);
[email protected]9f49afb2012-02-16 09:59:20827 rv = stream_->Write(drainable_, drainable_->BytesRemaining(),
[email protected]5eb431e22011-10-12 08:51:38828 callback.callback());
[email protected]8effd3f62011-03-25 16:29:07829 DCHECK_EQ(ERR_IO_PENDING, rv);
[email protected]4c2048a2009-03-24 21:02:01830 rv = callback.WaitForResult();
[email protected]9f49afb2012-02-16 09:59:20831 drainable_->DidConsume(total_bytes_written);
[email protected]4c2048a2009-03-24 21:02:01832 *total_bytes_written_ += total_bytes_written;
833 *total_bytes_read_ += total_bytes_read;
834 *data_read_ += data_read;
835 } else { // We're done writing all data. Start reading the data.
[email protected]8effd3f62011-03-25 16:29:07836 stream_->Seek(FROM_BEGIN, 0);
[email protected]4c2048a2009-03-24 21:02:01837
[email protected]5eb431e22011-10-12 08:51:38838 TestCompletionCallback callback;
[email protected]4c2048a2009-03-24 21:02:01839 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20840 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
841 rv = stream_->Read(buf, buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07842 if (rv == ERR_IO_PENDING) {
[email protected]b5717a42012-02-14 19:33:52843 MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
[email protected]4c2048a2009-03-24 21:02:01844 rv = callback.WaitForResult();
[email protected]4c2048a2009-03-24 21:02:01845 }
846 EXPECT_LE(0, rv);
847 if (rv <= 0)
848 break;
849 *total_bytes_read_ += rv;
[email protected]9f49afb2012-02-16 09:59:20850 data_read_->append(buf->data(), rv);
[email protected]4c2048a2009-03-24 21:02:01851 }
852 }
853
854 result_ = *total_bytes_written_;
855 have_result_ = true;
856 if (waiting_for_result_)
857 MessageLoop::current()->Quit();
858 }
859
860 int result_;
861 bool have_result_;
862 bool waiting_for_result_;
[email protected]8effd3f62011-03-25 16:29:07863 FileStream* stream_;
[email protected]4c2048a2009-03-24 21:02:01864 int* total_bytes_written_;
865 int* total_bytes_read_;
866 std::string* data_read_;
[email protected]5eb431e22011-10-12 08:51:38867 const CompletionCallback callback_;
[email protected]9f49afb2012-02-16 09:59:20868 scoped_refptr<IOBufferWithSize> test_data_;
869 scoped_refptr<DrainableIOBuffer> drainable_;
[email protected]4c2048a2009-03-24 21:02:01870
[email protected]5eb431e22011-10-12 08:51:38871 DISALLOW_COPY_AND_ASSIGN(TestWriteReadCompletionCallback);
[email protected]4c2048a2009-03-24 21:02:01872};
873
874TEST_F(FileStreamTest, AsyncWriteRead) {
875 int64 file_size;
876 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
877 EXPECT_TRUE(ok);
878
[email protected]10342992012-02-02 18:49:43879 FileStream stream(NULL);
[email protected]4c2048a2009-03-24 21:02:01880 int flags = base::PLATFORM_FILE_OPEN |
881 base::PLATFORM_FILE_READ |
882 base::PLATFORM_FILE_WRITE |
883 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:40884 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07885 EXPECT_EQ(OK, rv);
[email protected]4c2048a2009-03-24 21:02:01886
887 int64 total_bytes_avail = stream.Available();
888 EXPECT_EQ(file_size, total_bytes_avail);
889
[email protected]8effd3f62011-03-25 16:29:07890 int64 offset = stream.Seek(FROM_END, 0);
[email protected]4c2048a2009-03-24 21:02:01891 EXPECT_EQ(offset, file_size);
892
893 int total_bytes_written = 0;
894 int total_bytes_read = 0;
895 std::string data_read;
[email protected]5eb431e22011-10-12 08:51:38896 TestWriteReadCompletionCallback callback(&stream, &total_bytes_written,
[email protected]4c2048a2009-03-24 21:02:01897 &total_bytes_read, &data_read);
898
[email protected]9f49afb2012-02-16 09:59:20899 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
900 rv = stream.Write(buf, buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07901 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01902 rv = callback.WaitForResult();
903 EXPECT_LT(0, rv);
904 EXPECT_EQ(kTestDataSize, total_bytes_written);
905
[email protected]fe57eb22012-02-09 05:59:40906 stream.CloseSync();
[email protected]4c2048a2009-03-24 21:02:01907
908 ok = file_util::GetFileSize(temp_file_path(), &file_size);
909 EXPECT_TRUE(ok);
910 EXPECT_EQ(kTestDataSize * 2, file_size);
911
912 EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
913 const std::string kExpectedFileData =
914 std::string(kTestData) + std::string(kTestData);
915 EXPECT_EQ(kExpectedFileData, data_read);
916}
917
[email protected]5eb431e22011-10-12 08:51:38918class TestWriteCloseCompletionCallback {
[email protected]4c2048a2009-03-24 21:02:01919 public:
[email protected]5eb431e22011-10-12 08:51:38920 TestWriteCloseCompletionCallback(FileStream* stream, int* total_bytes_written)
[email protected]4c2048a2009-03-24 21:02:01921 : result_(0),
922 have_result_(false),
923 waiting_for_result_(false),
924 stream_(stream),
[email protected]5eb431e22011-10-12 08:51:38925 total_bytes_written_(total_bytes_written),
926 callback_(base::Bind(&TestWriteCloseCompletionCallback::OnComplete,
[email protected]9f49afb2012-02-16 09:59:20927 base::Unretained(this))),
928 test_data_(CreateTestDataBuffer()),
929 drainable_(new DrainableIOBuffer(test_data_, kTestDataSize)) {
930 }
[email protected]4c2048a2009-03-24 21:02:01931
932 int WaitForResult() {
933 DCHECK(!waiting_for_result_);
934 while (!have_result_) {
935 waiting_for_result_ = true;
936 MessageLoop::current()->Run();
937 waiting_for_result_ = false;
938 }
939 have_result_ = false; // auto-reset for next callback
940 return result_;
941 }
942
[email protected]5eb431e22011-10-12 08:51:38943 const CompletionCallback& callback() const { return callback_; }
944
[email protected]4c2048a2009-03-24 21:02:01945 private:
[email protected]5eb431e22011-10-12 08:51:38946 void OnComplete(int result) {
947 DCHECK_LT(0, result);
948 *total_bytes_written_ += result;
[email protected]4c2048a2009-03-24 21:02:01949
950 int rv;
951
952 if (*total_bytes_written_ != kTestDataSize) {
953 // Recurse to finish writing all data.
954 int total_bytes_written = 0;
[email protected]5eb431e22011-10-12 08:51:38955 TestWriteCloseCompletionCallback callback(stream_, &total_bytes_written);
[email protected]9f49afb2012-02-16 09:59:20956 rv = stream_->Write(drainable_, drainable_->BytesRemaining(),
[email protected]5eb431e22011-10-12 08:51:38957 callback.callback());
[email protected]8effd3f62011-03-25 16:29:07958 DCHECK_EQ(ERR_IO_PENDING, rv);
[email protected]4c2048a2009-03-24 21:02:01959 rv = callback.WaitForResult();
[email protected]9f49afb2012-02-16 09:59:20960 drainable_->DidConsume(total_bytes_written);
[email protected]4c2048a2009-03-24 21:02:01961 *total_bytes_written_ += total_bytes_written;
962 } else { // We're done writing all data. Close the file.
[email protected]fe57eb22012-02-09 05:59:40963 stream_->CloseSync();
[email protected]4c2048a2009-03-24 21:02:01964 }
965
966 result_ = *total_bytes_written_;
967 have_result_ = true;
968 if (waiting_for_result_)
969 MessageLoop::current()->Quit();
970 }
971
972 int result_;
973 bool have_result_;
974 bool waiting_for_result_;
[email protected]8effd3f62011-03-25 16:29:07975 FileStream* stream_;
[email protected]4c2048a2009-03-24 21:02:01976 int* total_bytes_written_;
[email protected]5eb431e22011-10-12 08:51:38977 const CompletionCallback callback_;
[email protected]9f49afb2012-02-16 09:59:20978 scoped_refptr<IOBufferWithSize> test_data_;
979 scoped_refptr<DrainableIOBuffer> drainable_;
[email protected]4c2048a2009-03-24 21:02:01980
[email protected]5eb431e22011-10-12 08:51:38981 DISALLOW_COPY_AND_ASSIGN(TestWriteCloseCompletionCallback);
[email protected]4c2048a2009-03-24 21:02:01982};
983
984TEST_F(FileStreamTest, AsyncWriteClose) {
985 int64 file_size;
986 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
987 EXPECT_TRUE(ok);
988
[email protected]10342992012-02-02 18:49:43989 FileStream stream(NULL);
[email protected]4c2048a2009-03-24 21:02:01990 int flags = base::PLATFORM_FILE_OPEN |
991 base::PLATFORM_FILE_READ |
992 base::PLATFORM_FILE_WRITE |
993 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:40994 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07995 EXPECT_EQ(OK, rv);
[email protected]4c2048a2009-03-24 21:02:01996
997 int64 total_bytes_avail = stream.Available();
998 EXPECT_EQ(file_size, total_bytes_avail);
999
[email protected]8effd3f62011-03-25 16:29:071000 int64 offset = stream.Seek(FROM_END, 0);
[email protected]4c2048a2009-03-24 21:02:011001 EXPECT_EQ(offset, file_size);
1002
1003 int total_bytes_written = 0;
[email protected]5eb431e22011-10-12 08:51:381004 TestWriteCloseCompletionCallback callback(&stream, &total_bytes_written);
[email protected]4c2048a2009-03-24 21:02:011005
[email protected]9f49afb2012-02-16 09:59:201006 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
1007 rv = stream.Write(buf, buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:071008 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:011009 total_bytes_written = callback.WaitForResult();
1010 EXPECT_LT(0, total_bytes_written);
1011 EXPECT_EQ(kTestDataSize, total_bytes_written);
1012
1013 ok = file_util::GetFileSize(temp_file_path(), &file_size);
1014 EXPECT_TRUE(ok);
1015 EXPECT_EQ(kTestDataSize * 2, file_size);
1016}
1017
[email protected]0643a492009-03-09 15:49:201018// Tests truncating a file.
1019TEST_F(FileStreamTest, Truncate) {
1020 int flags = base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE;
1021
[email protected]10342992012-02-02 18:49:431022 FileStream write_stream(NULL);
[email protected]fe57eb22012-02-09 05:59:401023 ASSERT_EQ(OK, write_stream.OpenSync(temp_file_path(), flags));
[email protected]0643a492009-03-09 15:49:201024
1025 // Write some data to the file.
1026 const char test_data[] = "0123456789";
[email protected]6b230f42012-02-15 04:08:411027 write_stream.WriteSync(test_data, arraysize(test_data));
[email protected]0643a492009-03-09 15:49:201028
1029 // Truncate the file.
1030 ASSERT_EQ(4, write_stream.Truncate(4));
1031
1032 // Write again.
[email protected]6b230f42012-02-15 04:08:411033 write_stream.WriteSync(test_data, 4);
[email protected]0643a492009-03-09 15:49:201034
1035 // Close the stream.
[email protected]fe57eb22012-02-09 05:59:401036 write_stream.CloseSync();
[email protected]0643a492009-03-09 15:49:201037
1038 // Read in the contents and make sure we get back what we expected.
1039 std::string read_contents;
[email protected]3fc364f92009-08-06 22:35:131040 EXPECT_TRUE(file_util::ReadFileToString(temp_file_path(), &read_contents));
[email protected]0643a492009-03-09 15:49:201041
[email protected]4c2048a2009-03-24 21:02:011042 EXPECT_EQ("01230123", read_contents);
[email protected]0643a492009-03-09 15:49:201043}
1044
[email protected]e3d66fde2012-02-17 22:10:341045TEST_F(FileStreamTest, AsyncBasicOpenClose) {
1046 FileStream stream(NULL);
1047 int flags = base::PLATFORM_FILE_OPEN |
1048 base::PLATFORM_FILE_READ |
1049 base::PLATFORM_FILE_ASYNC;
1050 TestCompletionCallback callback;
1051 int rv = stream.Open(temp_file_path(), flags, callback.callback());
1052 EXPECT_EQ(ERR_IO_PENDING, rv);
1053 EXPECT_EQ(OK, callback.WaitForResult());
1054 EXPECT_TRUE(stream.IsOpen());
1055
1056 stream.Close(callback.callback());
1057 EXPECT_EQ(OK, callback.WaitForResult());
1058 EXPECT_FALSE(stream.IsOpen());
1059}
1060
1061TEST_F(FileStreamTest, SyncCloseTwice) {
1062 FileStream stream(NULL);
1063 int flags = base::PLATFORM_FILE_OPEN |
1064 base::PLATFORM_FILE_READ;
1065 int rv = stream.OpenSync(temp_file_path(), flags);
1066 EXPECT_EQ(OK, rv);
1067 EXPECT_TRUE(stream.IsOpen());
1068
1069 // Closing twice should be safe.
1070 stream.CloseSync();
1071 EXPECT_FALSE(stream.IsOpen());
1072
1073 stream.CloseSync();
1074 EXPECT_FALSE(stream.IsOpen());
1075}
1076
1077TEST_F(FileStreamTest, AsyncCloseTwice) {
1078 FileStream stream(NULL);
1079 int flags = base::PLATFORM_FILE_OPEN |
1080 base::PLATFORM_FILE_READ |
1081 base::PLATFORM_FILE_ASYNC;
1082 TestCompletionCallback callback;
1083 int rv = stream.Open(temp_file_path(), flags, callback.callback());
1084 EXPECT_EQ(ERR_IO_PENDING, rv);
1085 EXPECT_EQ(OK, callback.WaitForResult());
1086 EXPECT_TRUE(stream.IsOpen());
1087
1088 // Closing twice should be safe.
1089 stream.Close(callback.callback());
1090 EXPECT_EQ(OK, callback.WaitForResult());
1091 EXPECT_FALSE(stream.IsOpen());
1092
1093 stream.Close(callback.callback());
1094 EXPECT_EQ(OK, callback.WaitForResult());
1095 EXPECT_FALSE(stream.IsOpen());
1096}
1097
[email protected]285673c2012-02-24 20:48:241098// TODO(satorux): This should be gone once all once all async clients are
1099// migrated to use Close(). crbug.com/114783
1100TEST_F(FileStreamTest, AsyncWriteAndCloseSync) {
1101 FileStream stream(NULL);
1102 int flags = base::PLATFORM_FILE_OPEN |
1103 base::PLATFORM_FILE_WRITE |
1104 base::PLATFORM_FILE_ASYNC;
1105 TestCompletionCallback callback;
1106 int rv = stream.Open(temp_file_path(), flags, callback.callback());
1107 EXPECT_EQ(ERR_IO_PENDING, rv);
1108 EXPECT_EQ(OK, callback.WaitForResult());
1109 EXPECT_TRUE(stream.IsOpen());
1110
1111 // Write some data asynchronously.
1112 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
1113 stream.Write(buf, buf->size(), callback.callback());
1114
1115 // Close the stream without waiting for the completion.
1116 stream.CloseSync();
1117}
1118
[email protected]4c2048a2009-03-24 21:02:011119} // namespace
[email protected]96d73822011-10-10 02:11:241120
[email protected]8effd3f62011-03-25 16:29:071121} // namespace net