blob: d3853ca16fb7aa948118ff75b116a6e5c6e19b79 [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:
[email protected]fba65f7b2012-03-15 05:22:1354 virtual void AddEntry(
55 EventType type,
56 const Source& source,
57 EventPhase phase,
58 const scoped_refptr<EventParameters>& params) OVERRIDE {
[email protected]e3d66fde2012-02-17 22:10:3459 if (type == TYPE_FILE_STREAM_CLOSE) {
60 on_closure_.Signal();
61 }
62 }
63
[email protected]d5cbd92a2012-02-29 12:43:2364 virtual uint32 NextID() OVERRIDE { return id_++; }
65 virtual LogLevel GetLogLevel() const OVERRIDE { return LOG_ALL; }
66 virtual void AddThreadSafeObserver(ThreadSafeObserver* observer,
67 LogLevel log_level) OVERRIDE {
68 NOTIMPLEMENTED();
69 }
70 virtual void SetObserverLogLevel(ThreadSafeObserver* observer,
71 LogLevel log_level) OVERRIDE {
72 NOTIMPLEMENTED();
73 }
74 virtual void RemoveThreadSafeObserver(ThreadSafeObserver* observer) OVERRIDE {
75 NOTIMPLEMENTED();
76 }
[email protected]e3d66fde2012-02-17 22:10:3477
78 private:
79 uint32 id_;
80 base::WaitableEvent on_closure_;
81};
82
[email protected]96d73822011-10-10 02:11:2483} // namespace
84
[email protected]21da6eb2008-11-03 17:18:1485class FileStreamTest : public PlatformTest {
86 public:
87 virtual void SetUp() {
88 PlatformTest::SetUp();
89
[email protected]33edeab2009-08-18 16:07:5590 file_util::CreateTemporaryFile(&temp_file_path_);
[email protected]7ff3f632009-10-13 18:43:3591 file_util::WriteFile(temp_file_path_, kTestData, kTestDataSize);
[email protected]21da6eb2008-11-03 17:18:1492 }
93 virtual void TearDown() {
94 file_util::Delete(temp_file_path_, false);
95
96 PlatformTest::TearDown();
97 }
[email protected]96d73822011-10-10 02:11:2498
[email protected]07167e8f2009-01-26 21:38:1199 const FilePath temp_file_path() const { return temp_file_path_; }
[email protected]96d73822011-10-10 02:11:24100
[email protected]21da6eb2008-11-03 17:18:14101 private:
[email protected]07167e8f2009-01-26 21:38:11102 FilePath temp_file_path_;
[email protected]21da6eb2008-11-03 17:18:14103};
104
[email protected]96d73822011-10-10 02:11:24105namespace {
106
[email protected]21da6eb2008-11-03 17:18:14107TEST_F(FileStreamTest, BasicOpenClose) {
[email protected]96d73822011-10-10 02:11:24108 base::PlatformFile file = base::kInvalidPlatformFileValue;
109 {
[email protected]10342992012-02-02 18:49:43110 FileStream stream(NULL);
[email protected]fe57eb22012-02-09 05:59:40111 int rv = stream.OpenSync(temp_file_path(),
[email protected]96d73822011-10-10 02:11:24112 base::PLATFORM_FILE_OPEN | base::PLATFORM_FILE_READ);
113 EXPECT_EQ(OK, rv);
114 EXPECT_TRUE(stream.IsOpen());
[email protected]84e0309f2012-02-24 01:56:59115 file = stream.GetPlatformFileForTesting();
[email protected]96d73822011-10-10 02:11:24116 }
117 EXPECT_NE(base::kInvalidPlatformFileValue, file);
118 base::PlatformFileInfo info;
119 // The file should be closed.
120 EXPECT_FALSE(base::GetPlatformFileInfo(file, &info));
121}
122
123TEST_F(FileStreamTest, FileHandleLeftOpen) {
124 bool created = false;
125 ASSERT_EQ(kTestDataSize,
126 file_util::WriteFile(temp_file_path(), kTestData, kTestDataSize));
127 int flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_READ;
128 base::PlatformFile file = base::CreatePlatformFile(
129 temp_file_path(), flags, &created, NULL);
130
131 {
132 // Seek to the beginning of the file and read.
[email protected]10342992012-02-02 18:49:43133 FileStream read_stream(file, flags, NULL);
[email protected]96d73822011-10-10 02:11:24134 EXPECT_TRUE(read_stream.IsOpen());
135 }
136
137 EXPECT_NE(base::kInvalidPlatformFileValue, file);
138 base::PlatformFileInfo info;
139 // The file should still be open.
140 EXPECT_TRUE(base::GetPlatformFileInfo(file, &info));
141 // Clean up.
142 EXPECT_TRUE(base::ClosePlatformFile(file));
[email protected]21da6eb2008-11-03 17:18:14143}
144
[email protected]92aad5222009-02-09 22:26:41145// Test the use of FileStream with a file handle provided at construction.
146TEST_F(FileStreamTest, UseFileHandle) {
147 bool created = false;
148
149 // 1. Test reading with a file handle.
150 ASSERT_EQ(kTestDataSize,
151 file_util::WriteFile(temp_file_path(), kTestData, kTestDataSize));
152 int flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_READ;
153 base::PlatformFile file = base::CreatePlatformFile(
[email protected]ed65fec2010-08-31 19:30:27154 temp_file_path(), flags, &created, NULL);
[email protected]92aad5222009-02-09 22:26:41155
156 // Seek to the beginning of the file and read.
[email protected]10342992012-02-02 18:49:43157 FileStream read_stream(file, flags, NULL);
[email protected]cf02541b2012-04-11 08:02:17158 ASSERT_EQ(0, read_stream.SeekSync(FROM_BEGIN, 0));
[email protected]92aad5222009-02-09 22:26:41159 ASSERT_EQ(kTestDataSize, read_stream.Available());
160 // Read into buffer and compare.
161 char buffer[kTestDataSize];
[email protected]5eb431e22011-10-12 08:51:38162 ASSERT_EQ(kTestDataSize,
[email protected]6b230f42012-02-15 04:08:41163 read_stream.ReadSync(buffer, kTestDataSize));
[email protected]92aad5222009-02-09 22:26:41164 ASSERT_EQ(0, memcmp(kTestData, buffer, kTestDataSize));
[email protected]fe57eb22012-02-09 05:59:40165 read_stream.CloseSync();
[email protected]92aad5222009-02-09 22:26:41166
167 // 2. Test writing with a file handle.
168 file_util::Delete(temp_file_path(), false);
169 flags = base::PLATFORM_FILE_OPEN_ALWAYS | base::PLATFORM_FILE_WRITE;
[email protected]ed65fec2010-08-31 19:30:27170 file = base::CreatePlatformFile(temp_file_path(), flags, &created, NULL);
[email protected]92aad5222009-02-09 22:26:41171
[email protected]10342992012-02-02 18:49:43172 FileStream write_stream(file, flags, NULL);
[email protected]cf02541b2012-04-11 08:02:17173 ASSERT_EQ(0, write_stream.SeekSync(FROM_BEGIN, 0));
[email protected]5eb431e22011-10-12 08:51:38174 ASSERT_EQ(kTestDataSize,
[email protected]6b230f42012-02-15 04:08:41175 write_stream.WriteSync(kTestData, kTestDataSize));
[email protected]fe57eb22012-02-09 05:59:40176 write_stream.CloseSync();
[email protected]92aad5222009-02-09 22:26:41177
178 // Read into buffer and compare to make sure the handle worked fine.
179 ASSERT_EQ(kTestDataSize,
180 file_util::ReadFile(temp_file_path(), buffer, kTestDataSize));
181 ASSERT_EQ(0, memcmp(kTestData, buffer, kTestDataSize));
182}
183
[email protected]21da6eb2008-11-03 17:18:14184TEST_F(FileStreamTest, UseClosedStream) {
[email protected]10342992012-02-02 18:49:43185 FileStream stream(NULL);
[email protected]21da6eb2008-11-03 17:18:14186
187 EXPECT_FALSE(stream.IsOpen());
188
189 // Try seeking...
[email protected]cf02541b2012-04-11 08:02:17190 int64 new_offset = stream.SeekSync(FROM_BEGIN, 5);
[email protected]8effd3f62011-03-25 16:29:07191 EXPECT_EQ(ERR_UNEXPECTED, new_offset);
[email protected]21da6eb2008-11-03 17:18:14192
193 // Try available...
194 int64 avail = stream.Available();
[email protected]8effd3f62011-03-25 16:29:07195 EXPECT_EQ(ERR_UNEXPECTED, avail);
[email protected]21da6eb2008-11-03 17:18:14196
197 // Try reading...
198 char buf[10];
[email protected]6b230f42012-02-15 04:08:41199 int rv = stream.ReadSync(buf, arraysize(buf));
[email protected]8effd3f62011-03-25 16:29:07200 EXPECT_EQ(ERR_UNEXPECTED, rv);
[email protected]21da6eb2008-11-03 17:18:14201}
202
203TEST_F(FileStreamTest, BasicRead) {
204 int64 file_size;
205 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
206 EXPECT_TRUE(ok);
207
[email protected]10342992012-02-02 18:49:43208 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38209 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14210 base::PLATFORM_FILE_READ;
[email protected]fe57eb22012-02-09 05:59:40211 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07212 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14213
214 int64 total_bytes_avail = stream.Available();
215 EXPECT_EQ(file_size, total_bytes_avail);
216
[email protected]4c2048a2009-03-24 21:02:01217 int total_bytes_read = 0;
[email protected]21da6eb2008-11-03 17:18:14218
219 std::string data_read;
220 for (;;) {
221 char buf[4];
[email protected]6b230f42012-02-15 04:08:41222 rv = stream.ReadSync(buf, arraysize(buf));
[email protected]21da6eb2008-11-03 17:18:14223 EXPECT_LE(0, rv);
224 if (rv <= 0)
225 break;
226 total_bytes_read += rv;
227 data_read.append(buf, rv);
228 }
229 EXPECT_EQ(file_size, total_bytes_read);
[email protected]4c2048a2009-03-24 21:02:01230 EXPECT_EQ(kTestData, data_read);
[email protected]21da6eb2008-11-03 17:18:14231}
232
233TEST_F(FileStreamTest, AsyncRead) {
234 int64 file_size;
235 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
236 EXPECT_TRUE(ok);
237
[email protected]10342992012-02-02 18:49:43238 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38239 int flags = base::PLATFORM_FILE_OPEN |
240 base::PLATFORM_FILE_READ |
[email protected]21da6eb2008-11-03 17:18:14241 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:40242 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07243 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14244
245 int64 total_bytes_avail = stream.Available();
246 EXPECT_EQ(file_size, total_bytes_avail);
247
[email protected]5eb431e22011-10-12 08:51:38248 TestCompletionCallback callback;
[email protected]21da6eb2008-11-03 17:18:14249
[email protected]4c2048a2009-03-24 21:02:01250 int total_bytes_read = 0;
[email protected]21da6eb2008-11-03 17:18:14251
252 std::string data_read;
253 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20254 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
255 rv = stream.Read(buf, buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07256 if (rv == ERR_IO_PENDING)
[email protected]21da6eb2008-11-03 17:18:14257 rv = callback.WaitForResult();
258 EXPECT_LE(0, rv);
259 if (rv <= 0)
260 break;
261 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20262 data_read.append(buf->data(), rv);
[email protected]21da6eb2008-11-03 17:18:14263 }
264 EXPECT_EQ(file_size, total_bytes_read);
[email protected]4c2048a2009-03-24 21:02:01265 EXPECT_EQ(kTestData, data_read);
266}
267
268TEST_F(FileStreamTest, AsyncRead_EarlyClose) {
269 int64 file_size;
270 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
271 EXPECT_TRUE(ok);
272
[email protected]10342992012-02-02 18:49:43273 FileStream stream(NULL);
[email protected]4c2048a2009-03-24 21:02:01274 int flags = base::PLATFORM_FILE_OPEN |
275 base::PLATFORM_FILE_READ |
276 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:40277 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07278 EXPECT_EQ(OK, rv);
[email protected]4c2048a2009-03-24 21:02:01279
280 int64 total_bytes_avail = stream.Available();
281 EXPECT_EQ(file_size, total_bytes_avail);
282
[email protected]5eb431e22011-10-12 08:51:38283 TestCompletionCallback callback;
[email protected]4c2048a2009-03-24 21:02:01284
[email protected]9f49afb2012-02-16 09:59:20285 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
286 rv = stream.Read(buf, buf->size(), callback.callback());
[email protected]fe57eb22012-02-09 05:59:40287 stream.CloseSync();
[email protected]3828a752009-06-03 23:05:59288 if (rv < 0) {
[email protected]8effd3f62011-03-25 16:29:07289 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3828a752009-06-03 23:05:59290 // The callback should not be called if the request is cancelled.
291 MessageLoop::current()->RunAllPending();
292 EXPECT_FALSE(callback.have_result());
293 } else {
[email protected]9f49afb2012-02-16 09:59:20294 EXPECT_EQ(std::string(kTestData, rv), std::string(buf->data(), rv));
[email protected]3828a752009-06-03 23:05:59295 }
[email protected]21da6eb2008-11-03 17:18:14296}
297
[email protected]06b802b2012-02-22 03:34:54298// Similar to AsyncRead_EarlyClose but deletes a stream instead, to ensure
299// that deleting a stream is safe while an async read is in flight.
300TEST_F(FileStreamTest, AsyncRead_EarlyDelete) {
301 int64 file_size;
302 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
303 EXPECT_TRUE(ok);
304
305 scoped_ptr<FileStream> stream(new FileStream(NULL));
306 int flags = base::PLATFORM_FILE_OPEN |
307 base::PLATFORM_FILE_READ |
308 base::PLATFORM_FILE_ASYNC;
309 TestCompletionCallback callback;
310 int rv = stream->Open(temp_file_path(), flags, callback.callback());
311 EXPECT_EQ(ERR_IO_PENDING, rv);
312 EXPECT_EQ(OK, callback.WaitForResult());
313
314 int64 total_bytes_avail = stream->Available();
315 EXPECT_EQ(file_size, total_bytes_avail);
316
317 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
318 rv = stream->Read(buf, buf->size(), callback.callback());
319 stream.reset(); // Delete instead of closing it.
320 if (rv < 0) {
321 EXPECT_EQ(ERR_IO_PENDING, rv);
322 // The callback should not be called if the request is cancelled.
323 MessageLoop::current()->RunAllPending();
324 EXPECT_FALSE(callback.have_result());
325 } else {
326 EXPECT_EQ(std::string(kTestData, rv), std::string(buf->data(), rv));
327 }
328}
329
[email protected]fa8b7232012-03-06 08:26:50330// Similar to AsyncRead_EarlyDelete but using a given file handler rather than
331// calling FileStream::Open, to ensure that deleting a stream with in-flight
332// operation without auto-closing feature is also ok.
333TEST_F(FileStreamTest, AsyncRead_EarlyDelete_NoAutoClose) {
334 int64 file_size;
335 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
336 EXPECT_TRUE(ok);
337
338 bool created = false;
339 int flags = base::PLATFORM_FILE_OPEN |
340 base::PLATFORM_FILE_READ |
341 base::PLATFORM_FILE_ASYNC;
342 base::PlatformFileError error_code = base::PLATFORM_FILE_ERROR_FAILED;
343 base::PlatformFile file = base::CreatePlatformFile(
344 temp_file_path(), flags, &created, &error_code);
345 EXPECT_EQ(base::PLATFORM_FILE_OK, error_code);
346
347 scoped_ptr<FileStream> stream(new FileStream(file, flags, NULL));
348 int64 total_bytes_avail = stream->Available();
349 EXPECT_EQ(file_size, total_bytes_avail);
350
351 TestCompletionCallback callback;
352 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
353 int rv = stream->Read(buf, buf->size(), callback.callback());
354 stream.reset(); // Delete instead of closing it.
355 if (rv < 0) {
356 EXPECT_EQ(ERR_IO_PENDING, rv);
357 // The callback should not be called if the request is cancelled.
358 MessageLoop::current()->RunAllPending();
359 EXPECT_FALSE(callback.have_result());
360 } else {
361 EXPECT_EQ(std::string(kTestData, rv), std::string(buf->data(), rv));
362 }
363
364 base::PlatformFileInfo info;
365 // The file should still be open.
366 EXPECT_TRUE(base::GetPlatformFileInfo(file, &info));
367 // Clean up.
368 EXPECT_TRUE(base::ClosePlatformFile(file));
369}
370
[email protected]21da6eb2008-11-03 17:18:14371TEST_F(FileStreamTest, BasicRead_FromOffset) {
372 int64 file_size;
373 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
374 EXPECT_TRUE(ok);
375
[email protected]10342992012-02-02 18:49:43376 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38377 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14378 base::PLATFORM_FILE_READ;
[email protected]fe57eb22012-02-09 05:59:40379 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07380 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14381
382 const int64 kOffset = 3;
[email protected]cf02541b2012-04-11 08:02:17383 int64 new_offset = stream.SeekSync(FROM_BEGIN, kOffset);
[email protected]21da6eb2008-11-03 17:18:14384 EXPECT_EQ(kOffset, new_offset);
385
386 int64 total_bytes_avail = stream.Available();
387 EXPECT_EQ(file_size - kOffset, total_bytes_avail);
388
389 int64 total_bytes_read = 0;
390
391 std::string data_read;
392 for (;;) {
393 char buf[4];
[email protected]6b230f42012-02-15 04:08:41394 rv = stream.ReadSync(buf, arraysize(buf));
[email protected]21da6eb2008-11-03 17:18:14395 EXPECT_LE(0, rv);
396 if (rv <= 0)
397 break;
398 total_bytes_read += rv;
399 data_read.append(buf, rv);
400 }
401 EXPECT_EQ(file_size - kOffset, total_bytes_read);
402 EXPECT_TRUE(data_read == kTestData + kOffset);
[email protected]4c2048a2009-03-24 21:02:01403 EXPECT_EQ(kTestData + kOffset, data_read);
[email protected]21da6eb2008-11-03 17:18:14404}
405
406TEST_F(FileStreamTest, AsyncRead_FromOffset) {
407 int64 file_size;
408 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
409 EXPECT_TRUE(ok);
410
[email protected]10342992012-02-02 18:49:43411 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38412 int flags = base::PLATFORM_FILE_OPEN |
413 base::PLATFORM_FILE_READ |
[email protected]21da6eb2008-11-03 17:18:14414 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:40415 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07416 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14417
[email protected]cf02541b2012-04-11 08:02:17418 TestInt64CompletionCallback callback64;
[email protected]21da6eb2008-11-03 17:18:14419 const int64 kOffset = 3;
[email protected]cf02541b2012-04-11 08:02:17420 rv = stream.Seek(FROM_BEGIN, kOffset, callback64.callback());
421 ASSERT_EQ(ERR_IO_PENDING, rv);
422 int64 new_offset = callback64.WaitForResult();
[email protected]21da6eb2008-11-03 17:18:14423 EXPECT_EQ(kOffset, new_offset);
424
425 int64 total_bytes_avail = stream.Available();
426 EXPECT_EQ(file_size - kOffset, total_bytes_avail);
427
[email protected]5eb431e22011-10-12 08:51:38428 TestCompletionCallback callback;
[email protected]21da6eb2008-11-03 17:18:14429
[email protected]4c2048a2009-03-24 21:02:01430 int total_bytes_read = 0;
[email protected]21da6eb2008-11-03 17:18:14431
432 std::string data_read;
433 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20434 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
435 rv = stream.Read(buf, buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07436 if (rv == ERR_IO_PENDING)
[email protected]21da6eb2008-11-03 17:18:14437 rv = callback.WaitForResult();
438 EXPECT_LE(0, rv);
439 if (rv <= 0)
440 break;
441 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20442 data_read.append(buf->data(), rv);
[email protected]21da6eb2008-11-03 17:18:14443 }
444 EXPECT_EQ(file_size - kOffset, total_bytes_read);
[email protected]4c2048a2009-03-24 21:02:01445 EXPECT_EQ(kTestData + kOffset, data_read);
[email protected]21da6eb2008-11-03 17:18:14446}
447
448TEST_F(FileStreamTest, SeekAround) {
[email protected]10342992012-02-02 18:49:43449 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38450 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14451 base::PLATFORM_FILE_READ;
[email protected]fe57eb22012-02-09 05:59:40452 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07453 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14454
455 const int64 kOffset = 3;
[email protected]cf02541b2012-04-11 08:02:17456 int64 new_offset = stream.SeekSync(FROM_BEGIN, kOffset);
[email protected]21da6eb2008-11-03 17:18:14457 EXPECT_EQ(kOffset, new_offset);
458
[email protected]cf02541b2012-04-11 08:02:17459 new_offset = stream.SeekSync(FROM_CURRENT, kOffset);
[email protected]21da6eb2008-11-03 17:18:14460 EXPECT_EQ(2 * kOffset, new_offset);
461
[email protected]cf02541b2012-04-11 08:02:17462 new_offset = stream.SeekSync(FROM_CURRENT, -kOffset);
[email protected]21da6eb2008-11-03 17:18:14463 EXPECT_EQ(kOffset, new_offset);
464
465 const int kTestDataLen = arraysize(kTestData) - 1;
466
[email protected]cf02541b2012-04-11 08:02:17467 new_offset = stream.SeekSync(FROM_END, -kTestDataLen);
468 EXPECT_EQ(0, new_offset);
469}
470
471TEST_F(FileStreamTest, AsyncSeekAround) {
472 FileStream stream(NULL);
473 int flags = base::PLATFORM_FILE_OPEN |
474 base::PLATFORM_FILE_ASYNC |
475 base::PLATFORM_FILE_READ;
476 int rv = stream.OpenSync(temp_file_path(), flags);
477 EXPECT_EQ(OK, rv);
478
479 TestInt64CompletionCallback callback;
480
481 const int64 kOffset = 3;
482 rv = stream.Seek(FROM_BEGIN, kOffset, callback.callback());
483 ASSERT_EQ(ERR_IO_PENDING, rv);
484 int64 new_offset = callback.WaitForResult();
485 EXPECT_EQ(kOffset, new_offset);
486
487 rv = stream.Seek(FROM_CURRENT, kOffset, callback.callback());
488 ASSERT_EQ(ERR_IO_PENDING, rv);
489 new_offset = callback.WaitForResult();
490 EXPECT_EQ(2 * kOffset, new_offset);
491
492 rv = stream.Seek(FROM_CURRENT, -kOffset, callback.callback());
493 ASSERT_EQ(ERR_IO_PENDING, rv);
494 new_offset = callback.WaitForResult();
495 EXPECT_EQ(kOffset, new_offset);
496
497 const int kTestDataLen = arraysize(kTestData) - 1;
498
499 rv = stream.Seek(FROM_END, -kTestDataLen, callback.callback());
500 ASSERT_EQ(ERR_IO_PENDING, rv);
501 new_offset = callback.WaitForResult();
[email protected]21da6eb2008-11-03 17:18:14502 EXPECT_EQ(0, new_offset);
503}
504
505TEST_F(FileStreamTest, BasicWrite) {
[email protected]10342992012-02-02 18:49:43506 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38507 int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
[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(0, file_size);
516
[email protected]6b230f42012-02-15 04:08:41517 rv = stream.WriteSync(kTestData, kTestDataSize);
[email protected]21da6eb2008-11-03 17:18:14518 EXPECT_EQ(kTestDataSize, rv);
[email protected]fe57eb22012-02-09 05:59:40519 stream.CloseSync();
[email protected]21da6eb2008-11-03 17:18:14520
521 ok = file_util::GetFileSize(temp_file_path(), &file_size);
522 EXPECT_TRUE(ok);
523 EXPECT_EQ(kTestDataSize, file_size);
524}
525
526TEST_F(FileStreamTest, AsyncWrite) {
[email protected]10342992012-02-02 18:49:43527 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38528 int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
529 base::PLATFORM_FILE_WRITE |
[email protected]21da6eb2008-11-03 17:18:14530 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:40531 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07532 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14533
534 int64 file_size;
535 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
536 EXPECT_TRUE(ok);
537 EXPECT_EQ(0, file_size);
538
[email protected]5eb431e22011-10-12 08:51:38539 TestCompletionCallback callback;
[email protected]4c2048a2009-03-24 21:02:01540 int total_bytes_written = 0;
[email protected]21da6eb2008-11-03 17:18:14541
[email protected]9f49afb2012-02-16 09:59:20542 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
543 scoped_refptr<DrainableIOBuffer> drainable =
544 new DrainableIOBuffer(buf, buf->size());
[email protected]21da6eb2008-11-03 17:18:14545 while (total_bytes_written != kTestDataSize) {
[email protected]9f49afb2012-02-16 09:59:20546 rv = stream.Write(drainable, drainable->BytesRemaining(),
[email protected]5eb431e22011-10-12 08:51:38547 callback.callback());
[email protected]8effd3f62011-03-25 16:29:07548 if (rv == ERR_IO_PENDING)
[email protected]21da6eb2008-11-03 17:18:14549 rv = callback.WaitForResult();
550 EXPECT_LT(0, rv);
551 if (rv <= 0)
552 break;
[email protected]9f49afb2012-02-16 09:59:20553 drainable->DidConsume(rv);
[email protected]21da6eb2008-11-03 17:18:14554 total_bytes_written += rv;
555 }
556 ok = file_util::GetFileSize(temp_file_path(), &file_size);
557 EXPECT_TRUE(ok);
558 EXPECT_EQ(file_size, total_bytes_written);
559}
560
[email protected]4c2048a2009-03-24 21:02:01561TEST_F(FileStreamTest, AsyncWrite_EarlyClose) {
[email protected]10342992012-02-02 18:49:43562 FileStream stream(NULL);
[email protected]4c2048a2009-03-24 21:02:01563 int flags = base::PLATFORM_FILE_CREATE_ALWAYS |
564 base::PLATFORM_FILE_WRITE |
565 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:40566 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07567 EXPECT_EQ(OK, rv);
[email protected]4c2048a2009-03-24 21:02:01568
569 int64 file_size;
570 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
571 EXPECT_TRUE(ok);
572 EXPECT_EQ(0, file_size);
573
[email protected]5eb431e22011-10-12 08:51:38574 TestCompletionCallback callback;
[email protected]4c2048a2009-03-24 21:02:01575
[email protected]9f49afb2012-02-16 09:59:20576 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
577 rv = stream.Write(buf, buf->size(), callback.callback());
[email protected]fe57eb22012-02-09 05:59:40578 stream.CloseSync();
[email protected]3828a752009-06-03 23:05:59579 if (rv < 0) {
[email protected]8effd3f62011-03-25 16:29:07580 EXPECT_EQ(ERR_IO_PENDING, rv);
[email protected]3828a752009-06-03 23:05:59581 // The callback should not be called if the request is cancelled.
582 MessageLoop::current()->RunAllPending();
583 EXPECT_FALSE(callback.have_result());
584 } else {
585 ok = file_util::GetFileSize(temp_file_path(), &file_size);
586 EXPECT_TRUE(ok);
587 EXPECT_EQ(file_size, rv);
588 }
[email protected]4c2048a2009-03-24 21:02:01589}
590
[email protected]21da6eb2008-11-03 17:18:14591TEST_F(FileStreamTest, BasicWrite_FromOffset) {
[email protected]10342992012-02-02 18:49:43592 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38593 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14594 base::PLATFORM_FILE_WRITE;
[email protected]fe57eb22012-02-09 05:59:40595 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07596 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14597
598 int64 file_size;
599 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
600 EXPECT_TRUE(ok);
601 EXPECT_EQ(kTestDataSize, file_size);
602
603 const int64 kOffset = 0;
[email protected]cf02541b2012-04-11 08:02:17604 int64 new_offset = stream.SeekSync(FROM_END, kOffset);
[email protected]21da6eb2008-11-03 17:18:14605 EXPECT_EQ(kTestDataSize, new_offset);
606
[email protected]6b230f42012-02-15 04:08:41607 rv = stream.WriteSync(kTestData, kTestDataSize);
[email protected]21da6eb2008-11-03 17:18:14608 EXPECT_EQ(kTestDataSize, rv);
[email protected]fe57eb22012-02-09 05:59:40609 stream.CloseSync();
[email protected]21da6eb2008-11-03 17:18:14610
611 ok = file_util::GetFileSize(temp_file_path(), &file_size);
612 EXPECT_TRUE(ok);
613 EXPECT_EQ(kTestDataSize * 2, file_size);
614}
615
616TEST_F(FileStreamTest, AsyncWrite_FromOffset) {
617 int64 file_size;
618 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
619 EXPECT_TRUE(ok);
620
[email protected]10342992012-02-02 18:49:43621 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38622 int flags = base::PLATFORM_FILE_OPEN |
[email protected]21da6eb2008-11-03 17:18:14623 base::PLATFORM_FILE_WRITE |
624 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:40625 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07626 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14627
[email protected]cf02541b2012-04-11 08:02:17628 TestInt64CompletionCallback callback64;
[email protected]21da6eb2008-11-03 17:18:14629 const int64 kOffset = 0;
[email protected]cf02541b2012-04-11 08:02:17630 rv = stream.Seek(FROM_END, kOffset, callback64.callback());
631 ASSERT_EQ(ERR_IO_PENDING, rv);
632 int64 new_offset = callback64.WaitForResult();
[email protected]21da6eb2008-11-03 17:18:14633 EXPECT_EQ(kTestDataSize, new_offset);
634
[email protected]5eb431e22011-10-12 08:51:38635 TestCompletionCallback callback;
[email protected]4c2048a2009-03-24 21:02:01636 int total_bytes_written = 0;
[email protected]21da6eb2008-11-03 17:18:14637
[email protected]9f49afb2012-02-16 09:59:20638 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
639 scoped_refptr<DrainableIOBuffer> drainable =
640 new DrainableIOBuffer(buf, buf->size());
[email protected]21da6eb2008-11-03 17:18:14641 while (total_bytes_written != kTestDataSize) {
[email protected]9f49afb2012-02-16 09:59:20642 rv = stream.Write(drainable, drainable->BytesRemaining(),
[email protected]5eb431e22011-10-12 08:51:38643 callback.callback());
[email protected]8effd3f62011-03-25 16:29:07644 if (rv == ERR_IO_PENDING)
[email protected]21da6eb2008-11-03 17:18:14645 rv = callback.WaitForResult();
646 EXPECT_LT(0, rv);
647 if (rv <= 0)
648 break;
[email protected]9f49afb2012-02-16 09:59:20649 drainable->DidConsume(rv);
[email protected]21da6eb2008-11-03 17:18:14650 total_bytes_written += rv;
651 }
652 ok = file_util::GetFileSize(temp_file_path(), &file_size);
653 EXPECT_TRUE(ok);
654 EXPECT_EQ(file_size, kTestDataSize * 2);
655}
656
657TEST_F(FileStreamTest, BasicReadWrite) {
658 int64 file_size;
659 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
660 EXPECT_TRUE(ok);
661
[email protected]10342992012-02-02 18:49:43662 FileStream stream(NULL);
[email protected]f0a51fb52009-03-05 12:46:38663 int flags = base::PLATFORM_FILE_OPEN |
664 base::PLATFORM_FILE_READ |
[email protected]21da6eb2008-11-03 17:18:14665 base::PLATFORM_FILE_WRITE;
[email protected]fe57eb22012-02-09 05:59:40666 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07667 EXPECT_EQ(OK, rv);
[email protected]21da6eb2008-11-03 17:18:14668
669 int64 total_bytes_avail = stream.Available();
670 EXPECT_EQ(file_size, total_bytes_avail);
671
[email protected]4c2048a2009-03-24 21:02:01672 int total_bytes_read = 0;
[email protected]21da6eb2008-11-03 17:18:14673
674 std::string data_read;
675 for (;;) {
676 char buf[4];
[email protected]6b230f42012-02-15 04:08:41677 rv = stream.ReadSync(buf, arraysize(buf));
[email protected]21da6eb2008-11-03 17:18:14678 EXPECT_LE(0, rv);
679 if (rv <= 0)
680 break;
681 total_bytes_read += rv;
682 data_read.append(buf, rv);
683 }
684 EXPECT_EQ(file_size, total_bytes_read);
685 EXPECT_TRUE(data_read == kTestData);
686
[email protected]6b230f42012-02-15 04:08:41687 rv = stream.WriteSync(kTestData, kTestDataSize);
[email protected]21da6eb2008-11-03 17:18:14688 EXPECT_EQ(kTestDataSize, rv);
[email protected]fe57eb22012-02-09 05:59:40689 stream.CloseSync();
[email protected]21da6eb2008-11-03 17:18:14690
691 ok = file_util::GetFileSize(temp_file_path(), &file_size);
692 EXPECT_TRUE(ok);
693 EXPECT_EQ(kTestDataSize * 2, file_size);
694}
695
[email protected]4c2048a2009-03-24 21:02:01696TEST_F(FileStreamTest, BasicWriteRead) {
697 int64 file_size;
698 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
699 EXPECT_TRUE(ok);
700
[email protected]10342992012-02-02 18:49:43701 FileStream stream(NULL);
[email protected]4c2048a2009-03-24 21:02:01702 int flags = base::PLATFORM_FILE_OPEN |
703 base::PLATFORM_FILE_READ |
704 base::PLATFORM_FILE_WRITE;
[email protected]fe57eb22012-02-09 05:59:40705 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07706 EXPECT_EQ(OK, rv);
[email protected]4c2048a2009-03-24 21:02:01707
708 int64 total_bytes_avail = stream.Available();
709 EXPECT_EQ(file_size, total_bytes_avail);
710
[email protected]cf02541b2012-04-11 08:02:17711 int64 offset = stream.SeekSync(FROM_END, 0);
[email protected]4c2048a2009-03-24 21:02:01712 EXPECT_EQ(offset, file_size);
713
[email protected]6b230f42012-02-15 04:08:41714 rv = stream.WriteSync(kTestData, kTestDataSize);
[email protected]4c2048a2009-03-24 21:02:01715 EXPECT_EQ(kTestDataSize, rv);
716
[email protected]cf02541b2012-04-11 08:02:17717 offset = stream.SeekSync(FROM_BEGIN, 0);
[email protected]4c2048a2009-03-24 21:02:01718 EXPECT_EQ(0, offset);
719
720 int64 total_bytes_read = 0;
721
722 std::string data_read;
723 for (;;) {
724 char buf[4];
[email protected]6b230f42012-02-15 04:08:41725 rv = stream.ReadSync(buf, arraysize(buf));
[email protected]4c2048a2009-03-24 21:02:01726 EXPECT_LE(0, rv);
727 if (rv <= 0)
728 break;
729 total_bytes_read += rv;
730 data_read.append(buf, rv);
731 }
[email protected]fe57eb22012-02-09 05:59:40732 stream.CloseSync();
[email protected]4c2048a2009-03-24 21:02:01733
734 ok = file_util::GetFileSize(temp_file_path(), &file_size);
735 EXPECT_TRUE(ok);
736 EXPECT_EQ(kTestDataSize * 2, file_size);
737 EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
738
739 const std::string kExpectedFileData =
740 std::string(kTestData) + std::string(kTestData);
741 EXPECT_EQ(kExpectedFileData, data_read);
742}
743
744TEST_F(FileStreamTest, BasicAsyncReadWrite) {
745 int64 file_size;
746 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
747 EXPECT_TRUE(ok);
748
[email protected]10342992012-02-02 18:49:43749 FileStream stream(NULL);
[email protected]4c2048a2009-03-24 21:02:01750 int flags = base::PLATFORM_FILE_OPEN |
751 base::PLATFORM_FILE_READ |
752 base::PLATFORM_FILE_WRITE |
753 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:40754 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07755 EXPECT_EQ(OK, rv);
[email protected]4c2048a2009-03-24 21:02:01756
757 int64 total_bytes_avail = stream.Available();
758 EXPECT_EQ(file_size, total_bytes_avail);
759
[email protected]5eb431e22011-10-12 08:51:38760 TestCompletionCallback callback;
[email protected]4c2048a2009-03-24 21:02:01761 int64 total_bytes_read = 0;
762
763 std::string data_read;
764 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20765 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
766 rv = stream.Read(buf, buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07767 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01768 rv = callback.WaitForResult();
769 EXPECT_LE(0, rv);
770 if (rv <= 0)
771 break;
772 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20773 data_read.append(buf->data(), rv);
[email protected]4c2048a2009-03-24 21:02:01774 }
775 EXPECT_EQ(file_size, total_bytes_read);
776 EXPECT_TRUE(data_read == kTestData);
777
778 int total_bytes_written = 0;
779
[email protected]9f49afb2012-02-16 09:59:20780 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
781 scoped_refptr<DrainableIOBuffer> drainable =
782 new DrainableIOBuffer(buf, buf->size());
[email protected]4c2048a2009-03-24 21:02:01783 while (total_bytes_written != kTestDataSize) {
[email protected]9f49afb2012-02-16 09:59:20784 rv = stream.Write(drainable, drainable->BytesRemaining(),
[email protected]5eb431e22011-10-12 08:51:38785 callback.callback());
[email protected]8effd3f62011-03-25 16:29:07786 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01787 rv = callback.WaitForResult();
788 EXPECT_LT(0, rv);
789 if (rv <= 0)
790 break;
[email protected]9f49afb2012-02-16 09:59:20791 drainable->DidConsume(rv);
[email protected]4c2048a2009-03-24 21:02:01792 total_bytes_written += rv;
793 }
794
[email protected]fe57eb22012-02-09 05:59:40795 stream.CloseSync();
[email protected]4c2048a2009-03-24 21:02:01796
797 ok = file_util::GetFileSize(temp_file_path(), &file_size);
798 EXPECT_TRUE(ok);
799 EXPECT_EQ(kTestDataSize * 2, file_size);
800}
801
802TEST_F(FileStreamTest, BasicAsyncWriteRead) {
803 int64 file_size;
804 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
805 EXPECT_TRUE(ok);
806
[email protected]10342992012-02-02 18:49:43807 FileStream stream(NULL);
[email protected]4c2048a2009-03-24 21:02:01808 int flags = base::PLATFORM_FILE_OPEN |
809 base::PLATFORM_FILE_READ |
810 base::PLATFORM_FILE_WRITE |
811 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:40812 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07813 EXPECT_EQ(OK, rv);
[email protected]4c2048a2009-03-24 21:02:01814
815 int64 total_bytes_avail = stream.Available();
816 EXPECT_EQ(file_size, total_bytes_avail);
817
[email protected]cf02541b2012-04-11 08:02:17818 TestInt64CompletionCallback callback64;
819 rv = stream.Seek(FROM_END, 0, callback64.callback());
820 ASSERT_EQ(ERR_IO_PENDING, rv);
821 int64 offset = callback64.WaitForResult();
[email protected]4c2048a2009-03-24 21:02:01822 EXPECT_EQ(offset, file_size);
823
[email protected]5eb431e22011-10-12 08:51:38824 TestCompletionCallback callback;
[email protected]4c2048a2009-03-24 21:02:01825 int total_bytes_written = 0;
826
[email protected]9f49afb2012-02-16 09:59:20827 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
828 scoped_refptr<DrainableIOBuffer> drainable =
829 new DrainableIOBuffer(buf, buf->size());
[email protected]4c2048a2009-03-24 21:02:01830 while (total_bytes_written != kTestDataSize) {
[email protected]9f49afb2012-02-16 09:59:20831 rv = stream.Write(drainable, drainable->BytesRemaining(),
[email protected]5eb431e22011-10-12 08:51:38832 callback.callback());
[email protected]8effd3f62011-03-25 16:29:07833 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01834 rv = callback.WaitForResult();
835 EXPECT_LT(0, rv);
836 if (rv <= 0)
837 break;
[email protected]9f49afb2012-02-16 09:59:20838 drainable->DidConsume(rv);
[email protected]4c2048a2009-03-24 21:02:01839 total_bytes_written += rv;
840 }
841
842 EXPECT_EQ(kTestDataSize, total_bytes_written);
843
[email protected]cf02541b2012-04-11 08:02:17844 rv = stream.Seek(FROM_BEGIN, 0, callback64.callback());
845 ASSERT_EQ(ERR_IO_PENDING, rv);
846 offset = callback64.WaitForResult();
[email protected]4c2048a2009-03-24 21:02:01847 EXPECT_EQ(0, offset);
848
849 int total_bytes_read = 0;
850
851 std::string data_read;
852 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20853 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
854 rv = stream.Read(buf, buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07855 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01856 rv = callback.WaitForResult();
857 EXPECT_LE(0, rv);
858 if (rv <= 0)
859 break;
860 total_bytes_read += rv;
[email protected]9f49afb2012-02-16 09:59:20861 data_read.append(buf->data(), rv);
[email protected]4c2048a2009-03-24 21:02:01862 }
[email protected]fe57eb22012-02-09 05:59:40863 stream.CloseSync();
[email protected]4c2048a2009-03-24 21:02:01864
865 ok = file_util::GetFileSize(temp_file_path(), &file_size);
866 EXPECT_TRUE(ok);
867 EXPECT_EQ(kTestDataSize * 2, file_size);
868
869 EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
870 const std::string kExpectedFileData =
871 std::string(kTestData) + std::string(kTestData);
872 EXPECT_EQ(kExpectedFileData, data_read);
873}
874
[email protected]5eb431e22011-10-12 08:51:38875class TestWriteReadCompletionCallback {
[email protected]4c2048a2009-03-24 21:02:01876 public:
[email protected]5eb431e22011-10-12 08:51:38877 TestWriteReadCompletionCallback(
[email protected]8effd3f62011-03-25 16:29:07878 FileStream* stream,
[email protected]4c2048a2009-03-24 21:02:01879 int* total_bytes_written,
880 int* total_bytes_read,
881 std::string* data_read)
882 : result_(0),
883 have_result_(false),
884 waiting_for_result_(false),
885 stream_(stream),
886 total_bytes_written_(total_bytes_written),
887 total_bytes_read_(total_bytes_read),
[email protected]5eb431e22011-10-12 08:51:38888 data_read_(data_read),
889 callback_(base::Bind(&TestWriteReadCompletionCallback::OnComplete,
[email protected]9f49afb2012-02-16 09:59:20890 base::Unretained(this))),
891 test_data_(CreateTestDataBuffer()),
892 drainable_(new DrainableIOBuffer(test_data_, kTestDataSize)) {
893 }
[email protected]4c2048a2009-03-24 21:02:01894
895 int WaitForResult() {
896 DCHECK(!waiting_for_result_);
897 while (!have_result_) {
898 waiting_for_result_ = true;
899 MessageLoop::current()->Run();
900 waiting_for_result_ = false;
901 }
902 have_result_ = false; // auto-reset for next callback
903 return result_;
904 }
905
[email protected]5eb431e22011-10-12 08:51:38906 const CompletionCallback& callback() const { return callback_; }
907
[email protected]4c2048a2009-03-24 21:02:01908 private:
[email protected]5eb431e22011-10-12 08:51:38909 void OnComplete(int result) {
910 DCHECK_LT(0, result);
911 *total_bytes_written_ += result;
[email protected]4c2048a2009-03-24 21:02:01912
913 int rv;
914
915 if (*total_bytes_written_ != kTestDataSize) {
916 // Recurse to finish writing all data.
917 int total_bytes_written = 0, total_bytes_read = 0;
918 std::string data_read;
[email protected]5eb431e22011-10-12 08:51:38919 TestWriteReadCompletionCallback callback(
[email protected]4c2048a2009-03-24 21:02:01920 stream_, &total_bytes_written, &total_bytes_read, &data_read);
[email protected]9f49afb2012-02-16 09:59:20921 rv = stream_->Write(drainable_, drainable_->BytesRemaining(),
[email protected]5eb431e22011-10-12 08:51:38922 callback.callback());
[email protected]8effd3f62011-03-25 16:29:07923 DCHECK_EQ(ERR_IO_PENDING, rv);
[email protected]4c2048a2009-03-24 21:02:01924 rv = callback.WaitForResult();
[email protected]9f49afb2012-02-16 09:59:20925 drainable_->DidConsume(total_bytes_written);
[email protected]4c2048a2009-03-24 21:02:01926 *total_bytes_written_ += total_bytes_written;
927 *total_bytes_read_ += total_bytes_read;
928 *data_read_ += data_read;
929 } else { // We're done writing all data. Start reading the data.
[email protected]cf02541b2012-04-11 08:02:17930 stream_->SeekSync(FROM_BEGIN, 0);
[email protected]4c2048a2009-03-24 21:02:01931
[email protected]5eb431e22011-10-12 08:51:38932 TestCompletionCallback callback;
[email protected]4c2048a2009-03-24 21:02:01933 for (;;) {
[email protected]9f49afb2012-02-16 09:59:20934 scoped_refptr<IOBufferWithSize> buf = new IOBufferWithSize(4);
935 rv = stream_->Read(buf, buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07936 if (rv == ERR_IO_PENDING) {
[email protected]b5717a42012-02-14 19:33:52937 MessageLoop::ScopedNestableTaskAllower allow(MessageLoop::current());
[email protected]4c2048a2009-03-24 21:02:01938 rv = callback.WaitForResult();
[email protected]4c2048a2009-03-24 21:02:01939 }
940 EXPECT_LE(0, rv);
941 if (rv <= 0)
942 break;
943 *total_bytes_read_ += rv;
[email protected]9f49afb2012-02-16 09:59:20944 data_read_->append(buf->data(), rv);
[email protected]4c2048a2009-03-24 21:02:01945 }
946 }
947
948 result_ = *total_bytes_written_;
949 have_result_ = true;
950 if (waiting_for_result_)
951 MessageLoop::current()->Quit();
952 }
953
954 int result_;
955 bool have_result_;
956 bool waiting_for_result_;
[email protected]8effd3f62011-03-25 16:29:07957 FileStream* stream_;
[email protected]4c2048a2009-03-24 21:02:01958 int* total_bytes_written_;
959 int* total_bytes_read_;
960 std::string* data_read_;
[email protected]5eb431e22011-10-12 08:51:38961 const CompletionCallback callback_;
[email protected]9f49afb2012-02-16 09:59:20962 scoped_refptr<IOBufferWithSize> test_data_;
963 scoped_refptr<DrainableIOBuffer> drainable_;
[email protected]4c2048a2009-03-24 21:02:01964
[email protected]5eb431e22011-10-12 08:51:38965 DISALLOW_COPY_AND_ASSIGN(TestWriteReadCompletionCallback);
[email protected]4c2048a2009-03-24 21:02:01966};
967
968TEST_F(FileStreamTest, AsyncWriteRead) {
969 int64 file_size;
970 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
971 EXPECT_TRUE(ok);
972
[email protected]10342992012-02-02 18:49:43973 FileStream stream(NULL);
[email protected]4c2048a2009-03-24 21:02:01974 int flags = base::PLATFORM_FILE_OPEN |
975 base::PLATFORM_FILE_READ |
976 base::PLATFORM_FILE_WRITE |
977 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:40978 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:07979 EXPECT_EQ(OK, rv);
[email protected]4c2048a2009-03-24 21:02:01980
981 int64 total_bytes_avail = stream.Available();
982 EXPECT_EQ(file_size, total_bytes_avail);
983
[email protected]cf02541b2012-04-11 08:02:17984 int64 offset = stream.SeekSync(FROM_END, 0);
[email protected]4c2048a2009-03-24 21:02:01985 EXPECT_EQ(offset, file_size);
986
987 int total_bytes_written = 0;
988 int total_bytes_read = 0;
989 std::string data_read;
[email protected]5eb431e22011-10-12 08:51:38990 TestWriteReadCompletionCallback callback(&stream, &total_bytes_written,
[email protected]4c2048a2009-03-24 21:02:01991 &total_bytes_read, &data_read);
992
[email protected]9f49afb2012-02-16 09:59:20993 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
994 rv = stream.Write(buf, buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:07995 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:01996 rv = callback.WaitForResult();
997 EXPECT_LT(0, rv);
998 EXPECT_EQ(kTestDataSize, total_bytes_written);
999
[email protected]fe57eb22012-02-09 05:59:401000 stream.CloseSync();
[email protected]4c2048a2009-03-24 21:02:011001
1002 ok = file_util::GetFileSize(temp_file_path(), &file_size);
1003 EXPECT_TRUE(ok);
1004 EXPECT_EQ(kTestDataSize * 2, file_size);
1005
1006 EXPECT_EQ(kTestDataSize * 2, total_bytes_read);
1007 const std::string kExpectedFileData =
1008 std::string(kTestData) + std::string(kTestData);
1009 EXPECT_EQ(kExpectedFileData, data_read);
1010}
1011
[email protected]5eb431e22011-10-12 08:51:381012class TestWriteCloseCompletionCallback {
[email protected]4c2048a2009-03-24 21:02:011013 public:
[email protected]5eb431e22011-10-12 08:51:381014 TestWriteCloseCompletionCallback(FileStream* stream, int* total_bytes_written)
[email protected]4c2048a2009-03-24 21:02:011015 : result_(0),
1016 have_result_(false),
1017 waiting_for_result_(false),
1018 stream_(stream),
[email protected]5eb431e22011-10-12 08:51:381019 total_bytes_written_(total_bytes_written),
1020 callback_(base::Bind(&TestWriteCloseCompletionCallback::OnComplete,
[email protected]9f49afb2012-02-16 09:59:201021 base::Unretained(this))),
1022 test_data_(CreateTestDataBuffer()),
1023 drainable_(new DrainableIOBuffer(test_data_, kTestDataSize)) {
1024 }
[email protected]4c2048a2009-03-24 21:02:011025
1026 int WaitForResult() {
1027 DCHECK(!waiting_for_result_);
1028 while (!have_result_) {
1029 waiting_for_result_ = true;
1030 MessageLoop::current()->Run();
1031 waiting_for_result_ = false;
1032 }
1033 have_result_ = false; // auto-reset for next callback
1034 return result_;
1035 }
1036
[email protected]5eb431e22011-10-12 08:51:381037 const CompletionCallback& callback() const { return callback_; }
1038
[email protected]4c2048a2009-03-24 21:02:011039 private:
[email protected]5eb431e22011-10-12 08:51:381040 void OnComplete(int result) {
1041 DCHECK_LT(0, result);
1042 *total_bytes_written_ += result;
[email protected]4c2048a2009-03-24 21:02:011043
1044 int rv;
1045
1046 if (*total_bytes_written_ != kTestDataSize) {
1047 // Recurse to finish writing all data.
1048 int total_bytes_written = 0;
[email protected]5eb431e22011-10-12 08:51:381049 TestWriteCloseCompletionCallback callback(stream_, &total_bytes_written);
[email protected]9f49afb2012-02-16 09:59:201050 rv = stream_->Write(drainable_, drainable_->BytesRemaining(),
[email protected]5eb431e22011-10-12 08:51:381051 callback.callback());
[email protected]8effd3f62011-03-25 16:29:071052 DCHECK_EQ(ERR_IO_PENDING, rv);
[email protected]4c2048a2009-03-24 21:02:011053 rv = callback.WaitForResult();
[email protected]9f49afb2012-02-16 09:59:201054 drainable_->DidConsume(total_bytes_written);
[email protected]4c2048a2009-03-24 21:02:011055 *total_bytes_written_ += total_bytes_written;
1056 } else { // We're done writing all data. Close the file.
[email protected]fe57eb22012-02-09 05:59:401057 stream_->CloseSync();
[email protected]4c2048a2009-03-24 21:02:011058 }
1059
1060 result_ = *total_bytes_written_;
1061 have_result_ = true;
1062 if (waiting_for_result_)
1063 MessageLoop::current()->Quit();
1064 }
1065
1066 int result_;
1067 bool have_result_;
1068 bool waiting_for_result_;
[email protected]8effd3f62011-03-25 16:29:071069 FileStream* stream_;
[email protected]4c2048a2009-03-24 21:02:011070 int* total_bytes_written_;
[email protected]5eb431e22011-10-12 08:51:381071 const CompletionCallback callback_;
[email protected]9f49afb2012-02-16 09:59:201072 scoped_refptr<IOBufferWithSize> test_data_;
1073 scoped_refptr<DrainableIOBuffer> drainable_;
[email protected]4c2048a2009-03-24 21:02:011074
[email protected]5eb431e22011-10-12 08:51:381075 DISALLOW_COPY_AND_ASSIGN(TestWriteCloseCompletionCallback);
[email protected]4c2048a2009-03-24 21:02:011076};
1077
1078TEST_F(FileStreamTest, AsyncWriteClose) {
1079 int64 file_size;
1080 bool ok = file_util::GetFileSize(temp_file_path(), &file_size);
1081 EXPECT_TRUE(ok);
1082
[email protected]10342992012-02-02 18:49:431083 FileStream stream(NULL);
[email protected]4c2048a2009-03-24 21:02:011084 int flags = base::PLATFORM_FILE_OPEN |
1085 base::PLATFORM_FILE_READ |
1086 base::PLATFORM_FILE_WRITE |
1087 base::PLATFORM_FILE_ASYNC;
[email protected]fe57eb22012-02-09 05:59:401088 int rv = stream.OpenSync(temp_file_path(), flags);
[email protected]8effd3f62011-03-25 16:29:071089 EXPECT_EQ(OK, rv);
[email protected]4c2048a2009-03-24 21:02:011090
1091 int64 total_bytes_avail = stream.Available();
1092 EXPECT_EQ(file_size, total_bytes_avail);
1093
[email protected]cf02541b2012-04-11 08:02:171094 int64 offset = stream.SeekSync(FROM_END, 0);
[email protected]4c2048a2009-03-24 21:02:011095 EXPECT_EQ(offset, file_size);
1096
1097 int total_bytes_written = 0;
[email protected]5eb431e22011-10-12 08:51:381098 TestWriteCloseCompletionCallback callback(&stream, &total_bytes_written);
[email protected]4c2048a2009-03-24 21:02:011099
[email protected]9f49afb2012-02-16 09:59:201100 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
1101 rv = stream.Write(buf, buf->size(), callback.callback());
[email protected]8effd3f62011-03-25 16:29:071102 if (rv == ERR_IO_PENDING)
[email protected]4c2048a2009-03-24 21:02:011103 total_bytes_written = callback.WaitForResult();
1104 EXPECT_LT(0, total_bytes_written);
1105 EXPECT_EQ(kTestDataSize, total_bytes_written);
1106
1107 ok = file_util::GetFileSize(temp_file_path(), &file_size);
1108 EXPECT_TRUE(ok);
1109 EXPECT_EQ(kTestDataSize * 2, file_size);
1110}
1111
[email protected]0643a492009-03-09 15:49:201112// Tests truncating a file.
1113TEST_F(FileStreamTest, Truncate) {
1114 int flags = base::PLATFORM_FILE_CREATE_ALWAYS | base::PLATFORM_FILE_WRITE;
1115
[email protected]10342992012-02-02 18:49:431116 FileStream write_stream(NULL);
[email protected]fe57eb22012-02-09 05:59:401117 ASSERT_EQ(OK, write_stream.OpenSync(temp_file_path(), flags));
[email protected]0643a492009-03-09 15:49:201118
1119 // Write some data to the file.
1120 const char test_data[] = "0123456789";
[email protected]6b230f42012-02-15 04:08:411121 write_stream.WriteSync(test_data, arraysize(test_data));
[email protected]0643a492009-03-09 15:49:201122
1123 // Truncate the file.
1124 ASSERT_EQ(4, write_stream.Truncate(4));
1125
1126 // Write again.
[email protected]6b230f42012-02-15 04:08:411127 write_stream.WriteSync(test_data, 4);
[email protected]0643a492009-03-09 15:49:201128
1129 // Close the stream.
[email protected]fe57eb22012-02-09 05:59:401130 write_stream.CloseSync();
[email protected]0643a492009-03-09 15:49:201131
1132 // Read in the contents and make sure we get back what we expected.
1133 std::string read_contents;
[email protected]3fc364f92009-08-06 22:35:131134 EXPECT_TRUE(file_util::ReadFileToString(temp_file_path(), &read_contents));
[email protected]0643a492009-03-09 15:49:201135
[email protected]4c2048a2009-03-24 21:02:011136 EXPECT_EQ("01230123", read_contents);
[email protected]0643a492009-03-09 15:49:201137}
1138
[email protected]e3d66fde2012-02-17 22:10:341139TEST_F(FileStreamTest, AsyncBasicOpenClose) {
1140 FileStream stream(NULL);
1141 int flags = base::PLATFORM_FILE_OPEN |
1142 base::PLATFORM_FILE_READ |
1143 base::PLATFORM_FILE_ASYNC;
1144 TestCompletionCallback callback;
1145 int rv = stream.Open(temp_file_path(), flags, callback.callback());
1146 EXPECT_EQ(ERR_IO_PENDING, rv);
1147 EXPECT_EQ(OK, callback.WaitForResult());
1148 EXPECT_TRUE(stream.IsOpen());
1149
1150 stream.Close(callback.callback());
1151 EXPECT_EQ(OK, callback.WaitForResult());
1152 EXPECT_FALSE(stream.IsOpen());
1153}
1154
1155TEST_F(FileStreamTest, SyncCloseTwice) {
1156 FileStream stream(NULL);
1157 int flags = base::PLATFORM_FILE_OPEN |
1158 base::PLATFORM_FILE_READ;
1159 int rv = stream.OpenSync(temp_file_path(), flags);
1160 EXPECT_EQ(OK, rv);
1161 EXPECT_TRUE(stream.IsOpen());
1162
1163 // Closing twice should be safe.
1164 stream.CloseSync();
1165 EXPECT_FALSE(stream.IsOpen());
1166
1167 stream.CloseSync();
1168 EXPECT_FALSE(stream.IsOpen());
1169}
1170
1171TEST_F(FileStreamTest, AsyncCloseTwice) {
1172 FileStream stream(NULL);
1173 int flags = base::PLATFORM_FILE_OPEN |
1174 base::PLATFORM_FILE_READ |
1175 base::PLATFORM_FILE_ASYNC;
1176 TestCompletionCallback callback;
1177 int rv = stream.Open(temp_file_path(), flags, callback.callback());
1178 EXPECT_EQ(ERR_IO_PENDING, rv);
1179 EXPECT_EQ(OK, callback.WaitForResult());
1180 EXPECT_TRUE(stream.IsOpen());
1181
1182 // Closing twice should be safe.
1183 stream.Close(callback.callback());
1184 EXPECT_EQ(OK, callback.WaitForResult());
1185 EXPECT_FALSE(stream.IsOpen());
1186
1187 stream.Close(callback.callback());
1188 EXPECT_EQ(OK, callback.WaitForResult());
1189 EXPECT_FALSE(stream.IsOpen());
1190}
1191
[email protected]285673c2012-02-24 20:48:241192// TODO(satorux): This should be gone once all once all async clients are
1193// migrated to use Close(). crbug.com/114783
1194TEST_F(FileStreamTest, AsyncWriteAndCloseSync) {
1195 FileStream stream(NULL);
1196 int flags = base::PLATFORM_FILE_OPEN |
1197 base::PLATFORM_FILE_WRITE |
1198 base::PLATFORM_FILE_ASYNC;
1199 TestCompletionCallback callback;
1200 int rv = stream.Open(temp_file_path(), flags, callback.callback());
1201 EXPECT_EQ(ERR_IO_PENDING, rv);
1202 EXPECT_EQ(OK, callback.WaitForResult());
1203 EXPECT_TRUE(stream.IsOpen());
1204
1205 // Write some data asynchronously.
1206 scoped_refptr<IOBufferWithSize> buf = CreateTestDataBuffer();
1207 stream.Write(buf, buf->size(), callback.callback());
1208
1209 // Close the stream without waiting for the completion.
1210 stream.CloseSync();
1211}
1212
[email protected]dbb747c2012-02-29 19:29:471213// TODO(satorux): This should be gone once all once all async clients are
1214// migrated to use Close(). crbug.com/114783
1215TEST_F(FileStreamTest, AsyncOpenAndCloseSync) {
1216 FileStream stream(NULL);
1217 int flags = base::PLATFORM_FILE_OPEN |
1218 base::PLATFORM_FILE_WRITE |
1219 base::PLATFORM_FILE_ASYNC;
1220 TestCompletionCallback open_callback;
1221 int rv = stream.Open(temp_file_path(), flags, open_callback.callback());
1222 EXPECT_EQ(ERR_IO_PENDING, rv);
1223
1224 // Close the stream without waiting for the completion. Should be safe.
1225 stream.CloseSync();
1226 // open_callback won't be called.
1227 EXPECT_FALSE(open_callback.have_result());
1228}
1229
1230TEST_F(FileStreamTest, AsyncOpenAndDelete) {
1231 scoped_ptr<FileStream> stream(new FileStream(NULL));
1232 int flags = base::PLATFORM_FILE_OPEN |
1233 base::PLATFORM_FILE_WRITE |
1234 base::PLATFORM_FILE_ASYNC;
1235 TestCompletionCallback open_callback;
1236 int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
1237 EXPECT_EQ(ERR_IO_PENDING, rv);
1238
1239 // Delete the stream without waiting for the open operation to be
1240 // complete. Should be safe.
1241 stream.reset();
1242 // open_callback won't be called.
1243 EXPECT_FALSE(open_callback.have_result());
1244}
1245
1246TEST_F(FileStreamTest, AsyncCloseAndDelete) {
1247 scoped_ptr<FileStream> stream(new FileStream(NULL));
1248 int flags = base::PLATFORM_FILE_OPEN |
1249 base::PLATFORM_FILE_WRITE |
1250 base::PLATFORM_FILE_ASYNC;
1251 TestCompletionCallback open_callback;
1252 int rv = stream->Open(temp_file_path(), flags, open_callback.callback());
1253 EXPECT_EQ(ERR_IO_PENDING, rv);
1254 EXPECT_EQ(OK, open_callback.WaitForResult());
1255 EXPECT_TRUE(stream->IsOpen());
1256
1257 TestCompletionCallback close_callback;
1258 stream->Close(close_callback.callback());
1259
1260 // Delete the stream without waiting for the close operation to be
1261 // complete. Should be safe.
1262 stream.reset();
1263 // close_callback won't be called.
1264 EXPECT_FALSE(close_callback.have_result());
1265}
1266
[email protected]4c2048a2009-03-24 21:02:011267} // namespace
[email protected]96d73822011-10-10 02:11:241268
[email protected]8effd3f62011-03-25 16:29:071269} // namespace net